mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-04 23:45:07 +00:00
fix: merge master (#1306)
* chore(site): dependabot deps (#1148) * chore(deps): bump highlight.js from 10.4.1 to 10.5.0 in /site (#1143) Bumps [highlight.js](https://github.com/highlightjs/highlight.js) from 10.4.1 to 10.5.0. - [Release notes](https://github.com/highlightjs/highlight.js/releases) - [Changelog](https://github.com/highlightjs/highlight.js/blob/master/CHANGES.md) - [Commits](https://github.com/highlightjs/highlight.js/compare/10.4.1...10.5.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @babel/plugin-transform-runtime in /site (#1144) Bumps [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-runtime) from 7.12.1 to 7.12.10. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.12.10/packages/babel-plugin-transform-runtime) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump sirv from 1.0.7 to 1.0.10 in /site (#1145) Bumps [sirv](https://github.com/lukeed/sirv) from 1.0.7 to 1.0.10. - [Release notes](https://github.com/lukeed/sirv/releases) - [Commits](https://github.com/lukeed/sirv/compare/v1.0.7...v1.0.10) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump rollup from 2.34.0 to 2.35.1 in /site (#1142) Bumps [rollup](https://github.com/rollup/rollup) from 2.34.0 to 2.35.1. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v2.34.0...v2.35.1) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @rollup/plugin-node-resolve in /site (#1141) Bumps [@rollup/plugin-node-resolve](https://github.com/rollup/plugins) from 10.0.0 to 11.0.1. - [Release notes](https://github.com/rollup/plugins/releases) - [Commits](https://github.com/rollup/plugins/compare/node-resolve-v10.0.0...commonjs-v11.0.1) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump marked from 1.2.5 to 1.2.7 in /site (#1140) Bumps [marked](https://github.com/markedjs/marked) from 1.2.5 to 1.2.7. - [Release notes](https://github.com/markedjs/marked/releases) - [Changelog](https://github.com/markedjs/marked/blob/master/release.config.js) - [Commits](https://github.com/markedjs/marked/compare/v1.2.5...v1.2.7) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @babel/core from 7.12.9 to 7.12.10 in /site (#1139) Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.12.9 to 7.12.10. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.12.10/packages/babel-core) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump rollup-plugin-svelte from 6.1.1 to 7.0.0 in /site (#1138) Bumps [rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte) from 6.1.1 to 7.0.0. - [Release notes](https://github.com/sveltejs/rollup-plugin-svelte/releases) - [Changelog](https://github.com/sveltejs/rollup-plugin-svelte/blob/master/CHANGELOG.md) - [Commits](https://github.com/sveltejs/rollup-plugin-svelte/compare/v6.1.1...v7.0.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @babel/preset-env from 7.12.1 to 7.12.11 in /site (#1137) Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.12.1 to 7.12.11. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.12.11/packages/babel-preset-env) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * downgrade svelte plugin Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(console): dependabot deps (#1147) * chore(deps-dev): bump @types/node from 14.14.13 to 14.14.19 in /console (#1146) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.13 to 14.14.19. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump ts-protoc-gen from 0.13.0 to 0.14.0 in /console (#1129) Bumps [ts-protoc-gen](https://github.com/improbable-eng/ts-protoc-gen) from 0.13.0 to 0.14.0. - [Release notes](https://github.com/improbable-eng/ts-protoc-gen/releases) - [Changelog](https://github.com/improbable-eng/ts-protoc-gen/blob/master/CHANGELOG.md) - [Commits](https://github.com/improbable-eng/ts-protoc-gen/compare/0.13.0...0.14.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular/language-service in /console (#1128) Bumps [@angular/language-service](https://github.com/angular/angular/tree/HEAD/packages/language-service) from 11.0.4 to 11.0.5. - [Release notes](https://github.com/angular/angular/releases) - [Changelog](https://github.com/angular/angular/blob/master/CHANGELOG.md) - [Commits](https://github.com/angular/angular/commits/11.0.5/packages/language-service) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular/cli from 11.0.4 to 11.0.5 in /console (#1127) Bumps [@angular/cli](https://github.com/angular/angular-cli) from 11.0.4 to 11.0.5. - [Release notes](https://github.com/angular/angular-cli/releases) - [Commits](https://github.com/angular/angular-cli/compare/v11.0.4...v11.0.5) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular-devkit/build-angular in /console (#1126) Bumps [@angular-devkit/build-angular](https://github.com/angular/angular-cli) from 0.1100.4 to 0.1100.5. - [Release notes](https://github.com/angular/angular-cli/releases) - [Commits](https://github.com/angular/angular-cli/commits) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Max Peintner <max@caos.ch> * audit Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: e-mail templates (#1158) * View definition added * Get templates and texts from the database. * Fill in texts in templates * Fill in texts in templates * Client API added * Weekly backup * Weekly backup * Daily backup * Weekly backup * Tests added * Corrections from merge branch * Fixes from pull request review * chore(console): dependencies (#1189) * chore(deps-dev): bump @angular/language-service in /console (#1187) Bumps [@angular/language-service](https://github.com/angular/angular/tree/HEAD/packages/language-service) from 11.0.5 to 11.0.9. - [Release notes](https://github.com/angular/angular/releases) - [Changelog](https://github.com/angular/angular/blob/master/CHANGELOG.md) - [Commits](https://github.com/angular/angular/commits/11.0.9/packages/language-service) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump google-proto-files from 2.3.0 to 2.4.0 in /console (#1186) Bumps [google-proto-files](https://github.com/googleapis/nodejs-proto-files) from 2.3.0 to 2.4.0. - [Release notes](https://github.com/googleapis/nodejs-proto-files/releases) - [Changelog](https://github.com/googleapis/nodejs-proto-files/blob/master/CHANGELOG.md) - [Commits](https://github.com/googleapis/nodejs-proto-files/compare/v2.3.0...v2.4.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @types/node from 14.14.19 to 14.14.21 in /console (#1185) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.19 to 14.14.21. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular/cli from 11.0.5 to 11.0.7 in /console (#1184) Bumps [@angular/cli](https://github.com/angular/angular-cli) from 11.0.5 to 11.0.7. - [Release notes](https://github.com/angular/angular-cli/releases) - [Commits](https://github.com/angular/angular-cli/compare/v11.0.5...v11.0.7) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump karma from 5.2.3 to 6.0.0 in /console (#1183) Bumps [karma](https://github.com/karma-runner/karma) from 5.2.3 to 6.0.0. - [Release notes](https://github.com/karma-runner/karma/releases) - [Changelog](https://github.com/karma-runner/karma/blob/master/CHANGELOG.md) - [Commits](https://github.com/karma-runner/karma/compare/v5.2.3...v6.0.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular-devkit/build-angular in /console (#1182) Bumps [@angular-devkit/build-angular](https://github.com/angular/angular-cli) from 0.1100.5 to 0.1100.7. - [Release notes](https://github.com/angular/angular-cli/releases) - [Commits](https://github.com/angular/angular-cli/commits) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix(console): trigger unauthenticated dialog only once (#1170) * fix: trigger dialog once * remove log * typed trigger * chore(console): dependencies (#1205) * chore(deps-dev): bump stylelint from 13.8.0 to 13.9.0 in /console (#1204) Bumps [stylelint](https://github.com/stylelint/stylelint) from 13.8.0 to 13.9.0. - [Release notes](https://github.com/stylelint/stylelint/releases) - [Changelog](https://github.com/stylelint/stylelint/blob/master/CHANGELOG.md) - [Commits](https://github.com/stylelint/stylelint/compare/13.8.0...13.9.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular/language-service in /console (#1203) Bumps [@angular/language-service](https://github.com/angular/angular/tree/HEAD/packages/language-service) from 11.0.9 to 11.1.0. - [Release notes](https://github.com/angular/angular/releases) - [Changelog](https://github.com/angular/angular/blob/master/CHANGELOG.md) - [Commits](https://github.com/angular/angular/commits/11.1.0/packages/language-service) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump karma from 6.0.0 to 6.0.1 in /console (#1202) Bumps [karma](https://github.com/karma-runner/karma) from 6.0.0 to 6.0.1. - [Release notes](https://github.com/karma-runner/karma/releases) - [Changelog](https://github.com/karma-runner/karma/blob/master/CHANGELOG.md) - [Commits](https://github.com/karma-runner/karma/compare/v6.0.0...v6.0.1) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular/cli from 11.0.7 to 11.1.1 in /console (#1201) Bumps [@angular/cli](https://github.com/angular/angular-cli) from 11.0.7 to 11.1.1. - [Release notes](https://github.com/angular/angular-cli/releases) - [Commits](https://github.com/angular/angular-cli/compare/v11.0.7...v11.1.1) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @types/jasmine from 3.6.2 to 3.6.3 in /console (#1200) Bumps [@types/jasmine](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jasmine) from 3.6.2 to 3.6.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jasmine) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Max Peintner <max@caos.ch> * chore(deps-dev): bump @types/node from 14.14.21 to 14.14.22 in /console (#1199) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.21 to 14.14.22. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular-devkit/build-angular in /console (#1198) Bumps [@angular-devkit/build-angular](https://github.com/angular/angular-cli) from 0.1100.7 to 0.1101.1. - [Release notes](https://github.com/angular/angular-cli/releases) - [Commits](https://github.com/angular/angular-cli/commits) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Max Peintner <max@caos.ch> * chore(deps): bump angularx-qrcode from 10.0.11 to 11.0.0 in /console (#1197) Bumps [angularx-qrcode](https://github.com/cordobo/angularx-qrcode) from 10.0.11 to 11.0.0. - [Release notes](https://github.com/cordobo/angularx-qrcode/releases) - [Commits](https://github.com/cordobo/angularx-qrcode/compare/10.0.11...11.0.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix pack lock Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: handle sequence correctly in subscription (#1209) * fix: correct master after merges again (#1230) * chore(docs): correct `iss` claim of jwt profile (#1229) * core(docs): correct `iss` claim of jwt profile * fix: correct master after merges again (#1230) * feat(login): new palette based styles (#1149) * chore(deps-dev): bump rollup from 2.33.2 to 2.34.0 in /site (#1040) Bumps [rollup](https://github.com/rollup/rollup) from 2.33.2 to 2.34.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v2.33.2...v2.34.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump svelte-i18n from 3.2.5 to 3.3.0 in /site (#1039) Bumps [svelte-i18n](https://github.com/kaisermann/svelte-i18n) from 3.2.5 to 3.3.0. - [Release notes](https://github.com/kaisermann/svelte-i18n/releases) - [Changelog](https://github.com/kaisermann/svelte-i18n/blob/main/CHANGELOG.md) - [Commits](https://github.com/kaisermann/svelte-i18n/compare/v3.2.5...v3.3.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @rollup/plugin-url from 5.0.1 to 6.0.0 in /site (#1038) Bumps [@rollup/plugin-url](https://github.com/rollup/plugins) from 5.0.1 to 6.0.0. - [Release notes](https://github.com/rollup/plugins/releases) - [Commits](https://github.com/rollup/plugins/compare/url-v5.0.1...url-v6.0.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump svelte from 3.29.7 to 3.30.1 in /site (#1037) Bumps [svelte](https://github.com/sveltejs/svelte) from 3.29.7 to 3.30.1. - [Release notes](https://github.com/sveltejs/svelte/releases) - [Changelog](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md) - [Commits](https://github.com/sveltejs/svelte/compare/v3.29.7...v3.30.1) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump marked from 1.2.4 to 1.2.5 in /site (#1036) Bumps [marked](https://github.com/markedjs/marked) from 1.2.4 to 1.2.5. - [Release notes](https://github.com/markedjs/marked/releases) - [Changelog](https://github.com/markedjs/marked/blob/master/release.config.js) - [Commits](https://github.com/markedjs/marked/compare/v1.2.4...v1.2.5) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @babel/core from 7.12.3 to 7.12.9 in /site (#1035) Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.12.3 to 7.12.9. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.12.9/packages/babel-core) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump rollup-plugin-svelte from 6.1.1 to 7.0.0 in /site (#1034) Bumps [rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte) from 6.1.1 to 7.0.0. - [Release notes](https://github.com/sveltejs/rollup-plugin-svelte/releases) - [Changelog](https://github.com/sveltejs/rollup-plugin-svelte/blob/master/CHANGELOG.md) - [Commits](https://github.com/sveltejs/rollup-plugin-svelte/compare/v6.1.1...v7.0.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @rollup/plugin-commonjs in /site (#1033) Bumps [@rollup/plugin-commonjs](https://github.com/rollup/plugins) from 15.1.0 to 17.0.0. - [Release notes](https://github.com/rollup/plugins/releases) - [Commits](https://github.com/rollup/plugins/compare/commonjs-v15.1.0...commonjs-v17.0.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @rollup/plugin-node-resolve in /site (#1032) Bumps [@rollup/plugin-node-resolve](https://github.com/rollup/plugins) from 10.0.0 to 11.0.0. - [Release notes](https://github.com/rollup/plugins/releases) - [Commits](https://github.com/rollup/plugins/compare/node-resolve-v10.0.0...commonjs-v11.0.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @babel/preset-env from 7.12.1 to 7.12.7 in /site (#1031) Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.12.1 to 7.12.7. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.12.7/packages/babel-preset-env) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * go * bundle files, lgn-color, legacy theme * remove old references * light dark context, button styles, zitadel brand * button theme, edit templates * typography theme mixins * input styles, container, extend light dark palette * footer, palette, container * container, label, assets, header * action container, input, typography label, adapt button theme * a and footer styles, adapt palette * user log profile, resourcetempurl * postinstall againnn * wrochage * rm local grpc * button elevation, helper for components * radio * radio button mixins, bundle * qr code styles, secret clipboard, icon pack * stroked buttons, icon buttons, header action, typography * fix password policy styles * account selection * account selection, lgn avatar * mocks * template fixes, animations scss * checkbox, register temp * checkbox appr * fix checkbox, remove input interference * select theme * avatar script, user selection, password policy validation fix * fix formfield state for register and change pwd * footer, main style, qr code fix, mfa type fix, account sel, checkbox * fotter tos, user select * reverse buttons for intial submit action * theme script, themed error messages, header img source * content wrapper, i18n, mobile * emptyline * idp mixins, fix unstyled html * register container * register layout, list themes, policy theme, register org * massive asset cleanup * fix source path, add missing icon, fix complexity refs, prefix * remove material icons, unused assets, fix icon font * move icon pack * avatar, contrast theme, error fix * zitadel css map * revert go mod * fix mfa verify actions * add idp styles * fix google colors, idp styles * fix: bugs * fix register options, google * fix script, mobile layout * precompile font selection * go mod tidy * assets and cleanup * input suffix, fix alignment, actions, add progress bar themes * progress bar mixins, layout fixes * remove test from loginname * cleanup comments, scripts * clear comments * fix external back button * fix mfa alignment * fix actions layout, on dom change listener for suffix * free tier change, success label * fix: button font line-height * remove tabindex * remove comment * remove comment * Update internal/ui/login/handler/password_handler.go Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Maximilian Peintner <csaq7175@uibk.ac.at> Co-authored-by: Livio Amstutz <livio.a@gmail.com> * chore(console): dependencies (#1233) * chore(deps-dev): bump @angular-devkit/build-angular in /console (#1214) Bumps [@angular-devkit/build-angular](https://github.com/angular/angular-cli) from 0.1101.1 to 0.1101.2. - [Release notes](https://github.com/angular/angular-cli/releases) - [Commits](https://github.com/angular/angular-cli/commits) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump karma from 6.0.1 to 6.0.3 in /console (#1215) Bumps [karma](https://github.com/karma-runner/karma) from 6.0.1 to 6.0.3. - [Release notes](https://github.com/karma-runner/karma/releases) - [Changelog](https://github.com/karma-runner/karma/blob/master/CHANGELOG.md) - [Commits](https://github.com/karma-runner/karma/compare/v6.0.1...v6.0.3) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular/language-service in /console (#1216) Bumps [@angular/language-service](https://github.com/angular/angular/tree/HEAD/packages/language-service) from 11.1.0 to 11.1.1. - [Release notes](https://github.com/angular/angular/releases) - [Changelog](https://github.com/angular/angular/blob/master/CHANGELOG.md) - [Commits](https://github.com/angular/angular/commits/11.1.1/packages/language-service) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular/cli from 11.1.1 to 11.1.2 in /console (#1217) Bumps [@angular/cli](https://github.com/angular/angular-cli) from 11.1.1 to 11.1.2. - [Release notes](https://github.com/angular/angular-cli/releases) - [Commits](https://github.com/angular/angular-cli/compare/v11.1.1...v11.1.2) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Max Peintner <max@caos.ch> * lock * site deps Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: get email texts with default language (#1238) * fix(login): mail verification (#1237) * fix: mail verification * not block, stroked * fix: issues of new login ui (#1241) * fix: i18n of register * fix: autofocus * feat(operator): zitadel and database operator (#1208) * feat(operator): add base for zitadel operator * fix(operator): changed pipeline to release operator * fix(operator): fmt with only one parameter * fix(operator): corrected workflow job name * fix(zitadelctl): added restore and backuplist command * fix(zitadelctl): scale for restore * chore(container): use scratch for deploy container * fix(zitadelctl): limit image to scratch * fix(migration): added migration scripts for newer version * fix(operator): changed handling of kubeconfig in operator logic * fix(operator): changed handling of secrets in operator logic * fix(operator): use new version of zitadel * fix(operator): added path for migrations * fix(operator): delete doublets of migration scripts * fix(operator): delete subpaths and integrate logic into init container * fix(operator): corrected path in dockerfile for local migrations * fix(operator): added migrations for cockroachdb-secure * fix(operator): delete logic for ambassador module * fix(operator): added read and write secret commands * fix(operator): correct and align operator pipeline with zitadel pipeline * fix(operator): correct yaml error in operator pipeline * fix(operator): correct action name in operator pipeline * fix(operator): correct case-sensitive filename in operator pipeline * fix(operator): upload artifacts from buildx output * fix(operator): corrected attribute spelling error * fix(operator): combined jobs for operator binary and image * fix(operator): added missing comma in operator pipeline * fix(operator): added codecov for operator image * fix(operator): added codecov for operator image * fix(testing): code changes for testing and several unit-tests (#1009) * fix(operator): usage of interface of kubernetes client for testing and several unit-tests * fix(operator): several unit-tests * fix(operator): several unit-tests * fix(operator): changed order for the operator logic * fix(operator): added version of zitadelctl from semantic release * fix(operator): corrected function call with version of zitadelctl * fix(operator): corrected function call with version of zitadelctl * fix(operator): add check output to operator release pipeline * fix(operator): set --short length everywhere to 12 * fix(operator): zitadel setup in job instead of exec with several unit tests * fix(operator): fixes to combine newest zitadel and testing branch * fix(operator): corrected path in Dockerfile * fix(operator): fixed unit-test that was ignored during changes * fix(operator): fixed unit-test that was ignored during changes * fix(operator): corrected Dockerfile to correctly use env variable * fix(operator): quickfix takeoff deployment * fix(operator): corrected the clusterrolename in the applied artifacts * fix: update secure migrations * fix(operator): migrations (#1057) * fix(operator): copied migrations from orbos repository * fix(operator): newest migrations * chore: use cockroach-secure * fix: rename migration * fix: remove insecure cockroach migrations Co-authored-by: Stefan Benz <stefan@caos.ch> * fix: finalize labels * fix(operator): cli logging concurrent and fixe deployment of operator during restore * fix: finalize labels and cli commands * fix: restore * chore: cockroachdb is always secure * chore: use orbos consistent-labels latest commit * test: make tests compatible with new labels * fix: default to sa token for start command * fix: use cockroachdb v12.02 * fix: don't delete flyway user * test: fix migration test * fix: use correct table qualifiers * fix: don't alter sequence ownership * fix: upgrade flyway * fix: change ownership of all dbs and tables to admin user * fix: change defaultdb user * fix: treat clientid status codes >= 400 as errors * fix: reconcile specified ZITADEL version, not binary version * fix: add ca-certs * fix: use latest orbos code * fix: use orbos with fixed race condition * fix: use latest ORBOS code * fix: use latest ORBOS code * fix: make migration and scaling around restoring work * fix(operator): move zitadel operator * chore(migrations): include owner change migration * feat(db): add code base for database operator * fix(db): change used image registry for database operator * fix(db): generated mock * fix(db): add accidentally ignored file * fix(db): add cockroachdb backup image to pipeline * fix(db): correct pipeline and image versions * fix(db): correct version of used orbos * fix(db): correct database import * fix(db): go mod tidy * fix(db): use new version for orbos * fix(migrations): include migrations into zitadelctl binary (#1211) * fix(db): use statik to integrate migrations into binary * fix(migrations): corrections unit tests and pipeline for integrated migrations into zitadelctl binary * fix(migrations): correction in dockerfile for pipeline build * fix(migrations): correction in dockerfile for pipeline build * fix(migrations): dockerfile changes for cache optimization * fix(database): correct used part-of label in database operator * fix(database): correct used selectable label in zitadel operator * fix(operator): correct lables for user secrets in zitadel operator * fix(operator): correct lables for service test in zitadel operator * fix: don't enable database features for user operations (#1227) * fix: don't enable database features for user operations * fix: omit database feature for connection info adapter * fix: use latest orbos version * fix: update ORBOS (#1240) Co-authored-by: Florian Forster <florian@caos.ch> Co-authored-by: Elio Bischof <eliobischof@gmail.com> * chore: add local migrate_local.go again (#1261) * chore: pass params in migrate_local.go (#1264) * fix: login policy bug (#1268) * fix: permissions on login policy multifactors and secondfactors * fix idp restriction Co-authored-by: Max Peintner <max@caos.ch> * fix: redirect after idp create (#1269) * fix(pipeline): corrected and combined operator and zitadel release into combined workflow (#1273) * fix(pipeline): combined operator and zitadel workflow to only release once * fix(pipeline): add dev releases for zitadelctl * fix(pipeline): delete unused name attribute * fix(pipeline): corrected use of github token env-variable * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected ref to get branch name for release * fix(pipeline): last corrections and use of different github action (#1270) * fix(pipeline): corrected loop for dev release * fix(pipeline): exclude tags from starting build workflow * fix(pipeline): use different release create action for already existing release * fix(pipeline): use correct name for release * fix(pipeline): push image with branch name tag and replace slashes with underscores * fix(pipeline): corrected indenting for yaml syntax * fix(pipeline): corrected handling of branch name * fix(pipeline): list artifacts after download * fix(pipeline): use github env for artifacts folder * fix(pipeline): replace slash with underscore in all jobs * fix(pipeline): pre-calculate refs for all jobs * fix(pipeline): corrected yaml indenting * fix(pipeline): deleted missed step * fix(pipeline): deleted unexpected input for dev-release * fix(pipeline): corrected echo for version in refs job * fix(pipeline): remove empty if in job * chore(pipeline): use correct path to zitadelctl binaries (#1277) * fix(pipeline): use correct version for zitadelctl build (#1278) * fix: usermemberships in authz (#1288) * fix: usermemberships in authz * fix: tests * fix: migration * fix: handler * fix: my usermemberships (#1290) * fix: my usermemberships * frontend Co-authored-by: Max Peintner <max@caos.ch> * fix: my usermemberships (#1291) * fix: my usermemberships * fix: migration * fix: migration (#1293) * fix(login): chrome prefill, org register suffix offset, loginname overflow (#1292) * fix: calculate offset, fix prefill * fix loginname, displayname overflow * feat: docs rehaul, fix missing context in console, quickstarts (#1212) * onboarding components, routing, steps * onboarding component, toc * fix onboarding mixin * header * refactor docs * fix layout * cleanup routing * docs routing * fix conventions * de en routing * docs, guide contents, nav * rem i18n support * fix routing from docs * rollup onwarn changes, preload * update svelte plugin, update rollup config * move docs * revert img style, remove code table * rem de completely * rollup optim, template * angular quickstart, quickstart overview page, update deps * fix link * pack, slug * prefetch binding, hidden links * export log * guards route ch * fix homepage * angular docs * docs * resolve fsh * overview * docs * docs * packages fix race condition * nav, home link * add vue, aspnet * doc optimizations * embed status pal * angular guide * angular guide * dotnet, angular guide * viewbox * typo * block onboarding route for non iam writers * set links from component data * fix: fetch org context in guard, more main cnt (#1192) * change get started guide, fix code blockquotes, typos * flutter guide * h2 spacing * highlight strong * plus * rm start sublinks * add proxy quickstart * regex * prevent outside click, fix project grant write Co-authored-by: Florian Forster <florian@caos.ch> Co-authored-by: Livio Amstutz <livio.a@gmail.com> * fix(console): auth guard, i18n (#1296) * fix: auth guard, i18n * Update console/src/app/guards/auth.guard.ts Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> * feat(console): OIDC setup (#1272) * feat: delete app * radio button mods, i18n * radio style, recommended flag * fix form, emitter, module, styles * app oidc * form value change * cleanup * app grid, new app detail, redirect, i18n * new uri format * seperate uris * cleanup export, create redirect * fix custom two way binding, switch * chore(deps): bump grpc from 1.24.3 to 1.24.5 in /console (#1287) * chore: add local migrate_local.go again (#1261) * chore: pass params in migrate_local.go (#1264) * fix: login policy bug (#1268) * fix: permissions on login policy multifactors and secondfactors * fix idp restriction Co-authored-by: Max Peintner <max@caos.ch> * fix: redirect after idp create (#1269) * fix(pipeline): corrected and combined operator and zitadel release into combined workflow (#1273) * fix(pipeline): combined operator and zitadel workflow to only release once * fix(pipeline): add dev releases for zitadelctl * fix(pipeline): delete unused name attribute * fix(pipeline): corrected use of github token env-variable * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected ref to get branch name for release * fix(pipeline): last corrections and use of different github action (#1270) * fix(pipeline): corrected loop for dev release * fix(pipeline): exclude tags from starting build workflow * fix(pipeline): use different release create action for already existing release * fix(pipeline): use correct name for release * fix(pipeline): push image with branch name tag and replace slashes with underscores * fix(pipeline): corrected indenting for yaml syntax * fix(pipeline): corrected handling of branch name * fix(pipeline): list artifacts after download * fix(pipeline): use github env for artifacts folder * fix(pipeline): replace slash with underscore in all jobs * fix(pipeline): pre-calculate refs for all jobs * fix(pipeline): corrected yaml indenting * fix(pipeline): deleted missed step * fix(pipeline): deleted unexpected input for dev-release * fix(pipeline): corrected echo for version in refs job * fix(pipeline): remove empty if in job * chore(pipeline): use correct path to zitadelctl binaries (#1277) * fix(pipeline): use correct version for zitadelctl build (#1278) * chore(deps): bump grpc from 1.24.3 to 1.24.5 in /console Bumps [grpc](https://github.com/grpc/grpc-node) from 1.24.3 to 1.24.5. - [Release notes](https://github.com/grpc/grpc-node/releases) - [Commits](https://github.com/grpc/grpc-node/compare/grpc@1.24.3...grpc@1.24.5) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @types/node from 14.14.22 to 14.14.28 in /console (#1286) * chore: add local migrate_local.go again (#1261) * chore: pass params in migrate_local.go (#1264) * fix: login policy bug (#1268) * fix: permissions on login policy multifactors and secondfactors * fix idp restriction Co-authored-by: Max Peintner <max@caos.ch> * fix: redirect after idp create (#1269) * fix(pipeline): corrected and combined operator and zitadel release into combined workflow (#1273) * fix(pipeline): combined operator and zitadel workflow to only release once * fix(pipeline): add dev releases for zitadelctl * fix(pipeline): delete unused name attribute * fix(pipeline): corrected use of github token env-variable * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected ref to get branch name for release * fix(pipeline): last corrections and use of different github action (#1270) * fix(pipeline): corrected loop for dev release * fix(pipeline): exclude tags from starting build workflow * fix(pipeline): use different release create action for already existing release * fix(pipeline): use correct name for release * fix(pipeline): push image with branch name tag and replace slashes with underscores * fix(pipeline): corrected indenting for yaml syntax * fix(pipeline): corrected handling of branch name * fix(pipeline): list artifacts after download * fix(pipeline): use github env for artifacts folder * fix(pipeline): replace slash with underscore in all jobs * fix(pipeline): pre-calculate refs for all jobs * fix(pipeline): corrected yaml indenting * fix(pipeline): deleted missed step * fix(pipeline): deleted unexpected input for dev-release * fix(pipeline): corrected echo for version in refs job * fix(pipeline): remove empty if in job * chore(pipeline): use correct path to zitadelctl binaries (#1277) * fix(pipeline): use correct version for zitadelctl build (#1278) * chore(deps-dev): bump @types/node from 14.14.22 to 14.14.28 in /console Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.22 to 14.14.28. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular-devkit/build-angular from 0.1101.2 to 0.1102.0 in /console (#1285) * chore: add local migrate_local.go again (#1261) * chore: pass params in migrate_local.go (#1264) * fix: login policy bug (#1268) * fix: permissions on login policy multifactors and secondfactors * fix idp restriction Co-authored-by: Max Peintner <max@caos.ch> * fix: redirect after idp create (#1269) * fix(pipeline): corrected and combined operator and zitadel release into combined workflow (#1273) * fix(pipeline): combined operator and zitadel workflow to only release once * fix(pipeline): add dev releases for zitadelctl * fix(pipeline): delete unused name attribute * fix(pipeline): corrected use of github token env-variable * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected ref to get branch name for release * fix(pipeline): last corrections and use of different github action (#1270) * fix(pipeline): corrected loop for dev release * fix(pipeline): exclude tags from starting build workflow * fix(pipeline): use different release create action for already existing release * fix(pipeline): use correct name for release * fix(pipeline): push image with branch name tag and replace slashes with underscores * fix(pipeline): corrected indenting for yaml syntax * fix(pipeline): corrected handling of branch name * fix(pipeline): list artifacts after download * fix(pipeline): use github env for artifacts folder * fix(pipeline): replace slash with underscore in all jobs * fix(pipeline): pre-calculate refs for all jobs * fix(pipeline): corrected yaml indenting * fix(pipeline): deleted missed step * fix(pipeline): deleted unexpected input for dev-release * fix(pipeline): corrected echo for version in refs job * fix(pipeline): remove empty if in job * chore(pipeline): use correct path to zitadelctl binaries (#1277) * fix(pipeline): use correct version for zitadelctl build (#1278) * chore(deps-dev): bump @angular-devkit/build-angular in /console Bumps [@angular-devkit/build-angular](https://github.com/angular/angular-cli) from 0.1101.2 to 0.1102.0. - [Release notes](https://github.com/angular/angular-cli/releases) - [Commits](https://github.com/angular/angular-cli/commits) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump typescript from 4.0.5 to 4.0.7 in /console (#1284) * chore: add local migrate_local.go again (#1261) * chore: pass params in migrate_local.go (#1264) * fix: login policy bug (#1268) * fix: permissions on login policy multifactors and secondfactors * fix idp restriction Co-authored-by: Max Peintner <max@caos.ch> * fix: redirect after idp create (#1269) * fix(pipeline): corrected and combined operator and zitadel release into combined workflow (#1273) * fix(pipeline): combined operator and zitadel workflow to only release once * fix(pipeline): add dev releases for zitadelctl * fix(pipeline): delete unused name attribute * fix(pipeline): corrected use of github token env-variable * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected ref to get branch name for release * fix(pipeline): last corrections and use of different github action (#1270) * fix(pipeline): corrected loop for dev release * fix(pipeline): exclude tags from starting build workflow * fix(pipeline): use different release create action for already existing release * fix(pipeline): use correct name for release * fix(pipeline): push image with branch name tag and replace slashes with underscores * fix(pipeline): corrected indenting for yaml syntax * fix(pipeline): corrected handling of branch name * fix(pipeline): list artifacts after download * fix(pipeline): use github env for artifacts folder * fix(pipeline): replace slash with underscore in all jobs * fix(pipeline): pre-calculate refs for all jobs * fix(pipeline): corrected yaml indenting * fix(pipeline): deleted missed step * fix(pipeline): deleted unexpected input for dev-release * fix(pipeline): corrected echo for version in refs job * fix(pipeline): remove empty if in job * chore(pipeline): use correct path to zitadelctl binaries (#1277) * fix(pipeline): use correct version for zitadelctl build (#1278) * chore(deps-dev): bump typescript from 4.0.5 to 4.0.7 in /console Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.0.5 to 4.0.7. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Commits](https://github.com/Microsoft/TypeScript/compare/v4.0.5...v4.0.7) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump karma from 6.0.3 to 6.1.1 in /console (#1283) * chore: add local migrate_local.go again (#1261) * chore: pass params in migrate_local.go (#1264) * fix: login policy bug (#1268) * fix: permissions on login policy multifactors and secondfactors * fix idp restriction Co-authored-by: Max Peintner <max@caos.ch> * fix: redirect after idp create (#1269) * fix(pipeline): corrected and combined operator and zitadel release into combined workflow (#1273) * fix(pipeline): combined operator and zitadel workflow to only release once * fix(pipeline): add dev releases for zitadelctl * fix(pipeline): delete unused name attribute * fix(pipeline): corrected use of github token env-variable * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected ref to get branch name for release * fix(pipeline): last corrections and use of different github action (#1270) * fix(pipeline): corrected loop for dev release * fix(pipeline): exclude tags from starting build workflow * fix(pipeline): use different release create action for already existing release * fix(pipeline): use correct name for release * fix(pipeline): push image with branch name tag and replace slashes with underscores * fix(pipeline): corrected indenting for yaml syntax * fix(pipeline): corrected handling of branch name * fix(pipeline): list artifacts after download * fix(pipeline): use github env for artifacts folder * fix(pipeline): replace slash with underscore in all jobs * fix(pipeline): pre-calculate refs for all jobs * fix(pipeline): corrected yaml indenting * fix(pipeline): deleted missed step * fix(pipeline): deleted unexpected input for dev-release * fix(pipeline): corrected echo for version in refs job * fix(pipeline): remove empty if in job * chore(pipeline): use correct path to zitadelctl binaries (#1277) * fix(pipeline): use correct version for zitadelctl build (#1278) * chore(deps-dev): bump karma from 6.0.3 to 6.1.1 in /console Bumps [karma](https://github.com/karma-runner/karma) from 6.0.3 to 6.1.1. - [Release notes](https://github.com/karma-runner/karma/releases) - [Changelog](https://github.com/karma-runner/karma/blob/master/CHANGELOG.md) - [Commits](https://github.com/karma-runner/karma/compare/v6.0.3...v6.1.1) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular/language-service from 11.1.1 to 11.2.0 in /console (#1282) * chore: add local migrate_local.go again (#1261) * chore: pass params in migrate_local.go (#1264) * fix: login policy bug (#1268) * fix: permissions on login policy multifactors and secondfactors * fix idp restriction Co-authored-by: Max Peintner <max@caos.ch> * fix: redirect after idp create (#1269) * fix(pipeline): corrected and combined operator and zitadel release into combined workflow (#1273) * fix(pipeline): combined operator and zitadel workflow to only release once * fix(pipeline): add dev releases for zitadelctl * fix(pipeline): delete unused name attribute * fix(pipeline): corrected use of github token env-variable * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected ref to get branch name for release * fix(pipeline): last corrections and use of different github action (#1270) * fix(pipeline): corrected loop for dev release * fix(pipeline): exclude tags from starting build workflow * fix(pipeline): use different release create action for already existing release * fix(pipeline): use correct name for release * fix(pipeline): push image with branch name tag and replace slashes with underscores * fix(pipeline): corrected indenting for yaml syntax * fix(pipeline): corrected handling of branch name * fix(pipeline): list artifacts after download * fix(pipeline): use github env for artifacts folder * fix(pipeline): replace slash with underscore in all jobs * fix(pipeline): pre-calculate refs for all jobs * fix(pipeline): corrected yaml indenting * fix(pipeline): deleted missed step * fix(pipeline): deleted unexpected input for dev-release * fix(pipeline): corrected echo for version in refs job * fix(pipeline): remove empty if in job * chore(pipeline): use correct path to zitadelctl binaries (#1277) * fix(pipeline): use correct version for zitadelctl build (#1278) * chore(deps-dev): bump @angular/language-service in /console Bumps [@angular/language-service](https://github.com/angular/angular/tree/HEAD/packages/language-service) from 11.1.1 to 11.2.0. - [Release notes](https://github.com/angular/angular/releases) - [Changelog](https://github.com/angular/angular/blob/master/CHANGELOG.md) - [Commits](https://github.com/angular/angular/commits/11.2.0/packages/language-service) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump stylelint from 13.9.0 to 13.10.0 in /console (#1281) * chore: add local migrate_local.go again (#1261) * chore: pass params in migrate_local.go (#1264) * fix: login policy bug (#1268) * fix: permissions on login policy multifactors and secondfactors * fix idp restriction Co-authored-by: Max Peintner <max@caos.ch> * fix: redirect after idp create (#1269) * fix(pipeline): corrected and combined operator and zitadel release into combined workflow (#1273) * fix(pipeline): combined operator and zitadel workflow to only release once * fix(pipeline): add dev releases for zitadelctl * fix(pipeline): delete unused name attribute * fix(pipeline): corrected use of github token env-variable * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected ref to get branch name for release * fix(pipeline): last corrections and use of different github action (#1270) * fix(pipeline): corrected loop for dev release * fix(pipeline): exclude tags from starting build workflow * fix(pipeline): use different release create action for already existing release * fix(pipeline): use correct name for release * fix(pipeline): push image with branch name tag and replace slashes with underscores * fix(pipeline): corrected indenting for yaml syntax * fix(pipeline): corrected handling of branch name * fix(pipeline): list artifacts after download * fix(pipeline): use github env for artifacts folder * fix(pipeline): replace slash with underscore in all jobs * fix(pipeline): pre-calculate refs for all jobs * fix(pipeline): corrected yaml indenting * fix(pipeline): deleted missed step * fix(pipeline): deleted unexpected input for dev-release * fix(pipeline): corrected echo for version in refs job * fix(pipeline): remove empty if in job * chore(pipeline): use correct path to zitadelctl binaries (#1277) * fix(pipeline): use correct version for zitadelctl build (#1278) * chore(deps-dev): bump stylelint from 13.9.0 to 13.10.0 in /console Bumps [stylelint](https://github.com/stylelint/stylelint) from 13.9.0 to 13.10.0. - [Release notes](https://github.com/stylelint/stylelint/releases) - [Changelog](https://github.com/stylelint/stylelint/blob/master/CHANGELOG.md) - [Commits](https://github.com/stylelint/stylelint/compare/13.9.0...13.10.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @angular/cli from 11.1.2 to 11.2.0 in /console (#1280) * chore: add local migrate_local.go again (#1261) * chore: pass params in migrate_local.go (#1264) * fix: login policy bug (#1268) * fix: permissions on login policy multifactors and secondfactors * fix idp restriction Co-authored-by: Max Peintner <max@caos.ch> * fix: redirect after idp create (#1269) * fix(pipeline): corrected and combined operator and zitadel release into combined workflow (#1273) * fix(pipeline): combined operator and zitadel workflow to only release once * fix(pipeline): add dev releases for zitadelctl * fix(pipeline): delete unused name attribute * fix(pipeline): corrected use of github token env-variable * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected ref to get branch name for release * fix(pipeline): last corrections and use of different github action (#1270) * fix(pipeline): corrected loop for dev release * fix(pipeline): exclude tags from starting build workflow * fix(pipeline): use different release create action for already existing release * fix(pipeline): use correct name for release * fix(pipeline): push image with branch name tag and replace slashes with underscores * fix(pipeline): corrected indenting for yaml syntax * fix(pipeline): corrected handling of branch name * fix(pipeline): list artifacts after download * fix(pipeline): use github env for artifacts folder * fix(pipeline): replace slash with underscore in all jobs * fix(pipeline): pre-calculate refs for all jobs * fix(pipeline): corrected yaml indenting * fix(pipeline): deleted missed step * fix(pipeline): deleted unexpected input for dev-release * fix(pipeline): corrected echo for version in refs job * fix(pipeline): remove empty if in job * chore(pipeline): use correct path to zitadelctl binaries (#1277) * fix(pipeline): use correct version for zitadelctl build (#1278) * chore(deps-dev): bump @angular/cli from 11.1.2 to 11.2.0 in /console Bumps [@angular/cli](https://github.com/angular/angular-cli) from 11.1.2 to 11.2.0. - [Release notes](https://github.com/angular/angular-cli/releases) - [Commits](https://github.com/angular/angular-cli/compare/v11.1.2...v11.2.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump stylelint-scss from 3.18.0 to 3.19.0 in /console (#1279) * chore: add local migrate_local.go again (#1261) * chore: pass params in migrate_local.go (#1264) * fix: login policy bug (#1268) * fix: permissions on login policy multifactors and secondfactors * fix idp restriction Co-authored-by: Max Peintner <max@caos.ch> * fix: redirect after idp create (#1269) * fix(pipeline): corrected and combined operator and zitadel release into combined workflow (#1273) * fix(pipeline): combined operator and zitadel workflow to only release once * fix(pipeline): add dev releases for zitadelctl * fix(pipeline): delete unused name attribute * fix(pipeline): corrected use of github token env-variable * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected download of artifacts to globally defined folder * fix(pipeline): corrected ref to get branch name for release * fix(pipeline): last corrections and use of different github action (#1270) * fix(pipeline): corrected loop for dev release * fix(pipeline): exclude tags from starting build workflow * fix(pipeline): use different release create action for already existing release * fix(pipeline): use correct name for release * fix(pipeline): push image with branch name tag and replace slashes with underscores * fix(pipeline): corrected indenting for yaml syntax * fix(pipeline): corrected handling of branch name * fix(pipeline): list artifacts after download * fix(pipeline): use github env for artifacts folder * fix(pipeline): replace slash with underscore in all jobs * fix(pipeline): pre-calculate refs for all jobs * fix(pipeline): corrected yaml indenting * fix(pipeline): deleted missed step * fix(pipeline): deleted unexpected input for dev-release * fix(pipeline): corrected echo for version in refs job * fix(pipeline): remove empty if in job * chore(pipeline): use correct path to zitadelctl binaries (#1277) * fix(pipeline): use correct version for zitadelctl build (#1278) * chore(deps-dev): bump stylelint-scss from 3.18.0 to 3.19.0 in /console Bumps [stylelint-scss](https://github.com/kristerkari/stylelint-scss) from 3.18.0 to 3.19.0. - [Release notes](https://github.com/kristerkari/stylelint-scss/releases) - [Changelog](https://github.com/kristerkari/stylelint-scss/blob/master/CHANGELOG.md) - [Commits](https://github.com/kristerkari/stylelint-scss/compare/3.18.0...3.19.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix custom change, highlight current config, links * info app-detail * app card component * applications list, fix project-grant-owner * fix member write * colorize warn in app * redirect warnings * Update console/src/assets/i18n/de.json Co-authored-by: Livio Amstutz <livio.a@gmail.com> * Update console/src/assets/i18n/de.json Co-authored-by: Livio Amstutz <livio.a@gmail.com> * Update console/src/assets/i18n/en.json Co-authored-by: Livio Amstutz <livio.a@gmail.com> * Update console/src/assets/i18n/de.json Co-authored-by: Livio Amstutz <livio.a@gmail.com> * Update console/src/assets/i18n/de.json Co-authored-by: Livio Amstutz <livio.a@gmail.com> * Update console/src/assets/i18n/de.json Co-authored-by: Livio Amstutz <livio.a@gmail.com> * Update console/src/assets/i18n/de.json Co-authored-by: Livio Amstutz <livio.a@gmail.com> * remove comments * Update console/src/assets/i18n/de.json Co-authored-by: Livio Amstutz <livio.a@gmail.com> * Update console/src/assets/i18n/de.json Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com> * fix: primary button color (#1297) * fix: remove status, admin line width (#1298) * feat: token introspection, api clients and auth method private_key_jwt (#1276) * introspect * testingapplication key * date * client keys * fix client keys * fix client keys * access tokens only for users * AuthMethodPrivateKeyJWT * client keys * set introspection info correctly * managae apis * update oidc pkg * cleanup * merge msater * set current sequence in migration * set current sequence in migration * set current sequence in migration * Apply suggestions from code review Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> * DeleteAuthNKeysByObjectID * ensure authn keys uptodate * update oidc version * merge master * merge master Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> * merge master * fix: version of migration for auth keys * merge master * merge master * fix step 11 Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Michael Waeger <49439088+michaelulrichwaeger@users.noreply.github.com> Co-authored-by: Maximilian Peintner <csaq7175@uibk.ac.at> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com> Co-authored-by: Florian Forster <florian@caos.ch> Co-authored-by: Elio Bischof <eliobischof@gmail.com>
This commit is contained in:
parent
ee86eb4399
commit
027a6386c0
91
.github/workflows/zitadel.yml
vendored
91
.github/workflows/zitadel.yml
vendored
@ -1,91 +0,0 @@
|
||||
name: Zitadel Release
|
||||
on: push
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.CR_PAT }}
|
||||
REGISTRY: ghcr.io
|
||||
NODE_VERSION: '12'
|
||||
GO_VERSION: '1.15'
|
||||
|
||||
jobs:
|
||||
container:
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- name: Source checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Set output
|
||||
id: branch
|
||||
run: echo ::set-output name=short_ref::${GITHUB_REF#refs/*/}
|
||||
- name: Check output
|
||||
run: echo ${{ steps.branch.outputs.short_ref }}
|
||||
- name: Generate Short SHA Container Tag
|
||||
id: vars
|
||||
run: echo "::set-output name=sha_short::SHA-$(git rev-parse --short=12 HEAD)"
|
||||
- name: Cache Docker layers
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildx-
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.CR_PAT }}
|
||||
registry: ${{ env.REGISTRY }}
|
||||
- uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./build/dockerfile
|
||||
platforms: linux/amd64
|
||||
tags: ${{ env.REGISTRY }}/${{ github.repository }}:${{ steps.vars.outputs.sha_short }},${{ env.REGISTRY }}/${{ github.repository }}:${{ steps.branch.outputs.short_ref }}
|
||||
push: true
|
||||
cache-from: type=local,src=/tmp/.buildx-cache
|
||||
cache-to: type=local,mode=max,dest=/tmp/.buildx-cache
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-18.04
|
||||
needs: [container]
|
||||
env:
|
||||
DOCKER_USERNAME: ${{ github.actor }}
|
||||
DOCKER_PASSWORD: ${{ secrets.CR_PAT }}
|
||||
steps:
|
||||
- name: Source checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Generate Short SHA Container Tag
|
||||
id: vars
|
||||
run: echo "::set-output name=sha_short::SHA-$(git rev-parse --short=12 HEAD)"
|
||||
- name: Docker Login
|
||||
run: docker login $REGISTRY -u $GITHUB_ACTOR -p $GITHUB_TOKEN
|
||||
- name: Docker Pull short-sha
|
||||
run: docker pull $REGISTRY/$GITHUB_REPOSITORY:${{ steps.vars.outputs.sha_short }}
|
||||
- name: Semantic Release
|
||||
id: semantic
|
||||
uses: cycjimmy/semantic-release-action@v2
|
||||
with:
|
||||
dry_run: false
|
||||
semantic_version: 17.0.4
|
||||
- name: Do something when a new release published
|
||||
if: steps.semantic.outputs.new_release_published == 'true'
|
||||
run: |
|
||||
echo ${{ steps.semantic.outputs.new_release_version }}
|
||||
echo ${{ steps.semantic.outputs.new_release_major_version }}
|
||||
echo ${{ steps.semantic.outputs.new_release_minor_version }}
|
||||
echo ${{ steps.semantic.outputs.new_release_patch_version }}
|
||||
- name: Docker Tag Version
|
||||
run: docker tag $REGISTRY/$GITHUB_REPOSITORY:${{ steps.vars.outputs.sha_short }} $REGISTRY/$GITHUB_REPOSITORY:${{ steps.semantic.outputs.new_release_version }}
|
||||
if: steps.semantic.outputs.new_release_published == 'true'
|
||||
- name: Docker Tag Latest
|
||||
run: docker tag $REGISTRY/$GITHUB_REPOSITORY:${{ steps.vars.outputs.sha_short }} $REGISTRY/$GITHUB_REPOSITORY:latest
|
||||
if: steps.semantic.outputs.new_release_published == 'true'
|
||||
- name: Docker Push Version
|
||||
run: docker push $REGISTRY/$GITHUB_REPOSITORY:${{ steps.semantic.outputs.new_release_version }}
|
||||
if: steps.semantic.outputs.new_release_published == 'true'
|
||||
- name: Docker Push Latest
|
||||
run: docker push $REGISTRY/$GITHUB_REPOSITORY:latest
|
||||
if: steps.semantic.outputs.new_release_published == 'true'
|
@ -6,15 +6,15 @@ module.exports = {
|
||||
["@semantic-release/github", {
|
||||
"assets": [
|
||||
{
|
||||
"path": ".artifacts/zitadel-darwin-amd64/zitadelctl",
|
||||
"path": "./artifacts/zitadelctl-darwin-amd64/zitadelctl-darwin-amd64",
|
||||
"label": "Zitadelctl Darwin x86_64"
|
||||
},
|
||||
{
|
||||
"path": ".artifacts/zitadel-linux-amd64/zitadelctl",
|
||||
"path": "./artifacts/zitadelctl-linux-amd64/zitadelctl-linux-amd64",
|
||||
"label": "Zitadelctl Linux x86_64"
|
||||
},
|
||||
{
|
||||
"path": ".artifacts/zitadel-windows-amd64/zitadelctl",
|
||||
"path": "./artifacts/zitadelctl-windows-amd64/zitadelctl-windows-amd64.exe",
|
||||
"label": "Zitadelctl Windows x86_64"
|
||||
}
|
||||
]
|
||||
|
@ -88,7 +88,7 @@ SetUp:
|
||||
Step6:
|
||||
DefaultLabelPolicy:
|
||||
PrimaryColor: '#222324'
|
||||
SecondaryColor: '#ffffff'
|
||||
SecondaryColor: '#ffffff'
|
||||
Step7:
|
||||
OTP: true
|
||||
Step8:
|
||||
@ -180,4 +180,4 @@ SetUp:
|
||||
Text: The domain {{.Domain}} has been claimed by an organisation. Your current user {{.Username}} is not part of this organisation. Therefore you'll have to change your email when you login. We have created a temporary username ({{.TempUsername}}) for this login.
|
||||
ButtonText: Login
|
||||
Step11:
|
||||
MigrateV1EventstoreToV2: true
|
||||
MigrateV1EventstoreToV2: $ZITADEL_MIGRATE_ES_V1
|
||||
|
@ -17,6 +17,7 @@ Metrics:
|
||||
MeterName: 'github.com/caos/zitadel'
|
||||
|
||||
AuthZ:
|
||||
Domain: $ZITADEL_DEFAULT_DOMAIN
|
||||
Repository:
|
||||
Eventstore:
|
||||
ServiceName: 'AuthZ'
|
||||
@ -186,6 +187,7 @@ API:
|
||||
Issuer: $ZITADEL_ISSUER
|
||||
DefaultLogoutRedirectURI: $ZITADEL_ACCOUNTS/logout/done
|
||||
CodeMethodS256: true
|
||||
AuthMethodPrivateKeyJWT: true
|
||||
StorageConfig:
|
||||
DefaultLoginURL: $ZITADEL_ACCOUNTS/login?authRequestID=
|
||||
DefaultAccessTokenLifetime: 12h
|
||||
@ -207,6 +209,9 @@ API:
|
||||
Token:
|
||||
Path: 'token'
|
||||
URL: '$ZITADEL_OAUTH/token'
|
||||
Introspection:
|
||||
Path: 'introspect'
|
||||
URL: '$ZITADEL_OAUTH/introspect'
|
||||
EndSession:
|
||||
Path: 'endsession'
|
||||
URL: '$ZITADEL_AUTHORIZE/endsession'
|
||||
|
@ -45,6 +45,7 @@ SystemDefaults:
|
||||
IncludeDigits: true
|
||||
IncludeSymbols: false
|
||||
MachineKeySize: 2048
|
||||
ClientKeySize: 2048
|
||||
Multifactors:
|
||||
OTP:
|
||||
Issuer: 'ZITADEL'
|
||||
|
3781
console/package-lock.json
generated
3781
console/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -33,7 +33,7 @@
|
||||
"file-saver": "^2.0.5",
|
||||
"google-proto-files": "^2.4.0",
|
||||
"google-protobuf": "^3.13.0",
|
||||
"grpc": "^1.24.3",
|
||||
"grpc": "^1.24.5",
|
||||
"grpc-web": "^1.2.1",
|
||||
"moment": "^2.29.1",
|
||||
"ngx-quicklink": "^0.2.6",
|
||||
@ -44,28 +44,28 @@
|
||||
"zone.js": "~0.11.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/cli": "~11.1.2",
|
||||
"@angular-devkit/build-angular": "~0.1101.2",
|
||||
"@angular/cli": "~11.2.0",
|
||||
"@angular-devkit/build-angular": "~0.1102.0",
|
||||
"@angular/compiler-cli": "~11.0.0",
|
||||
"@types/jasmine": "~3.6.3",
|
||||
"@angular/language-service": "~11.1.1",
|
||||
"@angular/language-service": "~11.2.0",
|
||||
"@types/jasminewd2": "~2.0.3",
|
||||
"@types/node": "^14.14.22",
|
||||
"@types/node": "^14.14.28",
|
||||
"codelyzer": "^6.0.0",
|
||||
"jasmine-core": "~3.6.0",
|
||||
"jasmine-spec-reporter": "~6.0.0",
|
||||
"karma": "~6.0.3",
|
||||
"karma": "~6.1.1",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage-istanbul-reporter": "~3.0.2",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "^1.5.0",
|
||||
"prettier": "^2.2.1",
|
||||
"protractor": "~7.0.0",
|
||||
"stylelint": "^13.9.0",
|
||||
"stylelint": "^13.10.0",
|
||||
"stylelint-config-standard": "^20.0.0",
|
||||
"stylelint-scss": "^3.18.0",
|
||||
"stylelint-scss": "^3.19.0",
|
||||
"ts-node": "~9.1.1",
|
||||
"tslint": "~6.1.3",
|
||||
"typescript": "^4.0.5"
|
||||
"typescript": "^4.0.7"
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,15 @@ const routes: Routes = [
|
||||
loadChildren: () => import('./pages/home/home.module').then(m => m.HomeModule),
|
||||
canActivate: [AuthGuard],
|
||||
},
|
||||
{
|
||||
path: 'firststeps',
|
||||
loadChildren: () => import('./modules/onboarding/onboarding.module')
|
||||
.then(m => m.OnboardingModule),
|
||||
canActivate: [AuthGuard, RoleGuard],
|
||||
data: {
|
||||
roles: ['iam.write'],
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'granted-projects',
|
||||
loadChildren: () => import('./pages/projects/granted-projects/granted-projects.module')
|
||||
|
@ -1,19 +1,25 @@
|
||||
<ng-container *ngIf="(authService.user | async) || {} as user">
|
||||
<ng-container *ngIf="((['iam.read$','iam.write$'] | hasRole)) as iamuser$">
|
||||
<mat-toolbar class="root-header">
|
||||
<button aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()">
|
||||
<button *ngIf="authenticationService.authenticated" aria-label="Toggle sidenav" mat-icon-button
|
||||
(click)="drawer.toggle()">
|
||||
<i class="icon las la-bars"></i>
|
||||
</button>
|
||||
<a *ngIf="(isHandset$ | async) == false" class="title" [routerLink]="['/']">
|
||||
<a class="title" [routerLink]="['/']">
|
||||
<img class="logo" alt="zitadel logo" *ngIf="componentCssClass == 'dark-theme'; else lighttheme"
|
||||
src="../assets/images/zitadel-logo-light.svg" />
|
||||
src="../assets/images/zitadel-logo-solo-light.svg" />
|
||||
<ng-template #lighttheme>
|
||||
<img alt="zitadel logo" class="logo" src="../assets/images/zitadel-logo-dark.svg" />
|
||||
<img alt="zitadel logo" class="logo" src="../assets/images/zitadel-logo-solo-dark.svg" />
|
||||
</ng-template>
|
||||
</a>
|
||||
|
||||
<button (click)="loadOrgs()" *ngIf="profile?.id && org" mat-button [matMenuTriggerFor]="menu"
|
||||
(menuOpened)="focusFilter()">{{org?.name ? org.name : 'NO NAME'}}
|
||||
<svg class="slash" viewBox="0 0 24 24" width="32" height="32" stroke="currentColor" stroke-width="1"
|
||||
stroke-linecap="round" stroke-linejoin="round" fill="none" shape-rendering="geometricPrecision">
|
||||
<path d="M16.88 3.549L7.12 20.451"></path>
|
||||
</svg>
|
||||
|
||||
<button class="org-button" (click)="loadOrgs()" *ngIf="profile?.id && org" mat-button
|
||||
[matMenuTriggerFor]="menu" (menuOpened)="focusFilter()">{{org?.name ? org.name : 'NO NAME'}}
|
||||
<mat-icon>
|
||||
arrow_drop_down</mat-icon>
|
||||
</button>
|
||||
@ -37,8 +43,8 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button class="show-all" mat-menu-item
|
||||
[routerLink]="[ '/org/overview' ]">{{'MENU.SHOWORGS' | translate}}</button>
|
||||
<button class="show-all" mat-menu-item [routerLink]="[ '/org/overview' ]">{{'MENU.SHOWORGS' |
|
||||
translate}}</button>
|
||||
|
||||
<ng-template appHasRole [appHasRole]="['org.create','iam.write']">
|
||||
<button mat-menu-item [routerLink]="[ '/org/create' ]">
|
||||
@ -49,23 +55,29 @@
|
||||
</mat-menu>
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<a class="doc-link" href="https://docs.zitadel.ch" mat-stroked-button
|
||||
target="_blank">{{'MENU.DOCUMENTATION' | translate}}</a>
|
||||
<a class="doc-link" href="https://docs.zitadel.ch" mat-stroked-button target="_blank">{{'MENU.DOCUMENTATION'
|
||||
| translate}}</a>
|
||||
<div (clickOutside)="closeAccountCard()" class="icon-container">
|
||||
<app-avatar *ngIf="user && (user.displayName || (user.firstName && user.lastName))"
|
||||
class="avatar dontcloseonclick" (click)="showAccount = !showAccount" [active]="showAccount"
|
||||
[name]="user.displayName ? user.displayName : (user.firstName + ' '+ user.lastName)" [size]="38">
|
||||
</app-avatar>
|
||||
<app-accounts-card @accounts class="a_card mat-elevation-z5" *ngIf="showAccount"
|
||||
<app-accounts-card @accounts class="a_card mat-elevation-z1" *ngIf="showAccount"
|
||||
(close)="showAccount = false" [profile]="profile" [iamuser]="iamuser$ | async">
|
||||
</app-accounts-card>
|
||||
</div>
|
||||
</mat-toolbar>
|
||||
<mat-drawer-container class="main-container">
|
||||
<mat-drawer #drawer class="sidenav" [mode]="(isHandset$ | async) ? 'over' : 'side'"
|
||||
[opened]="!(isHandset$ | async)">
|
||||
[opened]="!(isHandset$ | async) && authenticationService.authenticated">
|
||||
<div class="side-column">
|
||||
<div class="list">
|
||||
<a @navitem class="nav-item" [routerLinkActive]="['active']"
|
||||
[routerLinkActiveOptions]="{ exact: true }" [routerLink]="['/']">
|
||||
<i class="icon las la-home"></i>
|
||||
<span class="label">{{ 'MENU.DASHBOARD' | translate }}</span>
|
||||
</a>
|
||||
|
||||
<ng-container *ngIf="authenticationService.authenticationChanged | async">
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.PERSONAL' | translate}}" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }"
|
||||
@ -163,6 +175,13 @@
|
||||
</ng-container>
|
||||
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<div class="toc-line">
|
||||
<a class="toc" href="https://zitadel.ch/pdf/agb.pdf" alt="Terms and Conditions"
|
||||
target="_blank">{{'MENU.TOC'
|
||||
| translate}}</a>
|
||||
<span> </span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
</div>
|
||||
|
@ -11,9 +11,14 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
||||
.org-button {
|
||||
font-weight: bold;
|
||||
padding-right: .5rem;
|
||||
}
|
||||
|
||||
.logo {
|
||||
max-height: 50px;
|
||||
width: 160px;
|
||||
max-height: 40px;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.title {
|
||||
@ -22,7 +27,6 @@
|
||||
font-size: 1.2rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.2rem;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.context-menu {
|
||||
@ -82,7 +86,7 @@
|
||||
padding-top: 60px;
|
||||
|
||||
.sidenav {
|
||||
width: 300px;
|
||||
width: 280px;
|
||||
border-right: none;
|
||||
|
||||
.side-column {
|
||||
@ -90,6 +94,7 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
height: calc(100% - 60px);
|
||||
|
||||
.list {
|
||||
width: 100%;
|
||||
@ -123,7 +128,6 @@
|
||||
.label {
|
||||
margin-bottom: 0;
|
||||
font-size: 14px;
|
||||
letter-spacing: .05em;
|
||||
}
|
||||
|
||||
.c_label {
|
||||
@ -132,7 +136,6 @@
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
letter-spacing: .03em;
|
||||
|
||||
.count {
|
||||
font-size: 12px;
|
||||
@ -140,7 +143,7 @@
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #00000010;
|
||||
// background-color: #00000010;
|
||||
border-top-right-radius: 1.5rem;
|
||||
border-bottom-right-radius: 1.5rem;
|
||||
}
|
||||
@ -148,6 +151,7 @@
|
||||
&.active {
|
||||
border-top-right-radius: 1.5rem;
|
||||
border-bottom-right-radius: 1.5rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,6 +164,43 @@
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.toc-line {
|
||||
margin: 2rem 2rem;
|
||||
|
||||
.toc {
|
||||
font-size: 12px;
|
||||
color: var(--grey);
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.sp-status {
|
||||
font-size: 12px;
|
||||
color: var(--grey);
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.sp-status .sp-status-badge.sp-status-ok {
|
||||
background: darkgreen;
|
||||
}
|
||||
.sp-status .sp-status-badge.sp-status-scheduled {
|
||||
background: darkblue;
|
||||
}
|
||||
.sp-status .sp-status-badge.sp-status-minor {
|
||||
background: darkorange;
|
||||
}
|
||||
.sp-status .sp-status-badge.sp-status-major {
|
||||
background: darkred;
|
||||
}
|
||||
}
|
||||
|
||||
.logout-button {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ export class AppComponent implements OnDestroy {
|
||||
}
|
||||
|
||||
private getProjectCount(): void {
|
||||
this.authService.isAllowed(['project.read$']).subscribe((allowed) => {
|
||||
this.authService.isAllowed(['project.read']).subscribe((allowed) => {
|
||||
if (allowed) {
|
||||
this.mgmtService.SearchProjects(0, 0);
|
||||
|
||||
|
@ -23,6 +23,7 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
||||
import { AuthConfig, OAuthModule, OAuthStorage } from 'angular-oauth2-oidc';
|
||||
import { QuicklinkModule } from 'ngx-quicklink';
|
||||
import { OnboardingModule } from 'src/app/modules/onboarding/onboarding.module';
|
||||
import { RegExpPipeModule } from 'src/app/pipes/regexp-pipe/regexp-pipe.module';
|
||||
|
||||
import { environment } from '../environments/environment';
|
||||
@ -121,6 +122,7 @@ const authConfig: AuthConfig = {
|
||||
WarnDialogModule,
|
||||
MatDialogModule,
|
||||
RegExpPipeModule,
|
||||
OnboardingModule,
|
||||
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }),
|
||||
],
|
||||
providers: [
|
||||
|
@ -3,18 +3,19 @@ import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot } from '@angul
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { AuthenticationService } from '../services/authentication.service';
|
||||
import { GrpcAuthService } from '../services/grpc-auth.service';
|
||||
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class AuthGuard implements CanActivate {
|
||||
constructor(private auth: AuthenticationService) { }
|
||||
constructor(private auth: AuthenticationService, private authService: GrpcAuthService) { }
|
||||
|
||||
public canActivate(
|
||||
_: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot,
|
||||
): Observable<boolean> | Promise<boolean> | boolean {
|
||||
): Observable<boolean> | Promise<boolean> | Promise<any> | boolean {
|
||||
if (!this.auth.authenticated) {
|
||||
return this.auth.authenticate();
|
||||
}
|
||||
|
5
console/src/app/modules/app-card/app-card.component.html
Normal file
5
console/src/app/modules/app-card/app-card.component.html
Normal file
@ -0,0 +1,5 @@
|
||||
<div class="cnsl-app-card" [ngClass]="{'web': type == OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB,
|
||||
'useragent': type == OIDCApplicationType.OIDCAPPLICATIONTYPE_USER_AGENT,
|
||||
'native': type == OIDCApplicationType.OIDCAPPLICATIONTYPE_NATIVE}">
|
||||
<ng-content></ng-content>
|
||||
</div>
|
49
console/src/app/modules/app-card/app-card.component.scss
Normal file
49
console/src/app/modules/app-card/app-card.component.scss
Normal file
@ -0,0 +1,49 @@
|
||||
@import '~@angular/material/theming';
|
||||
|
||||
@mixin app-card-theme($theme) {
|
||||
/* stylelint-disable */
|
||||
$primary: map-get($theme, primary);
|
||||
$primary-dark: mat-color($primary, A900);
|
||||
$accent: map-get($theme, accent);
|
||||
$is-dark-theme: map-get($theme, is-dark);
|
||||
$accent-color: mat-color($primary, 500);
|
||||
/* stylelint-enable */
|
||||
|
||||
.cnsl-app-card {
|
||||
padding: 1rem;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
animation: all .2s;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 2rem;
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
margin: 1rem;
|
||||
text-transform: uppercase;
|
||||
border-radius: .5rem;
|
||||
font-weight: 800;
|
||||
background-color: $primary-dark;
|
||||
transition: background-color box-shadow .3s ease-in;
|
||||
|
||||
&.web {
|
||||
background-color: rgb(80, 110, 110);
|
||||
color: white;
|
||||
border: none;
|
||||
}
|
||||
|
||||
&.native {
|
||||
background-color: #595d80;
|
||||
color: white;
|
||||
border: none;
|
||||
}
|
||||
|
||||
&.useragent {
|
||||
background-color: #6a506e;
|
||||
color: white;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
14
console/src/app/modules/app-card/app-card.component.ts
Normal file
14
console/src/app/modules/app-card/app-card.component.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { OIDCApplicationType } from 'src/app/proto/generated/management_pb';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-app-card',
|
||||
templateUrl: './app-card.component.html',
|
||||
styleUrls: ['./app-card.component.scss'],
|
||||
})
|
||||
export class AppCardComponent {
|
||||
@Input() public outline: boolean = false;
|
||||
@Input() public type!: OIDCApplicationType;
|
||||
|
||||
public OIDCApplicationType: any = OIDCApplicationType;
|
||||
}
|
15
console/src/app/modules/app-card/app-card.module.ts
Normal file
15
console/src/app/modules/app-card/app-card.module.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { AppCardComponent } from './app-card.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppCardComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
],
|
||||
exports: [
|
||||
AppCardComponent,
|
||||
],
|
||||
})
|
||||
export class AppCardModule { }
|
@ -0,0 +1,35 @@
|
||||
<div class="radio-button-wrapper">
|
||||
<ng-container *ngFor="let method of authMethods; index as i">
|
||||
<input type="radio" [disabled]="method.disabled" (change)="emitChange()" [value]="method.key" [id]="method.key"
|
||||
[(ngModel)]="selected" />
|
||||
<label class="cnsl-radio-button" [ngClass]="{'first': i == 0, 'last': i == authMethods.length - 1}"
|
||||
[for]="method.key">
|
||||
<div class="recommended" [ngClass]="{'not': method.notRecommended}"
|
||||
*ngIf="method.recommended || method.notRecommended">
|
||||
{{(method.recommended ?
|
||||
'APP.OIDC.RECOMMENDED' : 'APP.OIDC.NOTRECOMMENDED') | translate }}</div>
|
||||
|
||||
<div class="cnsl-radio-header" [ngStyle]="{'background': method.background}">
|
||||
<span>{{method.prefix}}</span>
|
||||
<div class="current" *ngIf="current == method.key">{{'APP.OIDC.CURRENT' | translate}}</div>
|
||||
</div>
|
||||
<p>{{method.titleI18nKey | translate}}</p>
|
||||
<p class="type-desc">{{method.descI18nKey | translate}}</p>
|
||||
<span class="fill-space"></span>
|
||||
<div class="app-specs">
|
||||
<div class="row" *ngIf="method && method.responseType != undefined">
|
||||
<span>{{'APP.OIDC.RESPONSE' | translate}}</span>
|
||||
<span>{{('APP.OIDC.RESPONSE'+method.responseType.toString()) | translate}}</span>
|
||||
</div>
|
||||
<div class="row" *ngIf="method.grantType != undefined">
|
||||
<span>{{'APP.GRANT' | translate}}</span>
|
||||
<span>{{('APP.OIDC.GRANT'+method.grantType.toString()) | translate}}</span>
|
||||
</div>
|
||||
<div class="row" *ngIf="method.authMethod != undefined">
|
||||
<span>{{'APP.OIDC.AUTHMETHOD' | translate}}</span>
|
||||
<span>{{('APP.OIDC.AUTHMETHOD'+method.authMethod.toString()) | translate}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</ng-container>
|
||||
</div>
|
@ -0,0 +1,140 @@
|
||||
|
||||
@import '~@angular/material/theming';
|
||||
|
||||
.radio-button-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
margin: 0;
|
||||
padding-bottom: .5rem;
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
@mixin app-auth-method-radio-theme($theme) {
|
||||
$primary: map-get($theme, primary);
|
||||
$primary-color: mat-color($primary, 500);
|
||||
$is-dark-theme: map-get($theme, is-dark);
|
||||
|
||||
input[type="radio"]{
|
||||
appearance: none;
|
||||
opacity: 0;
|
||||
display: none;
|
||||
}
|
||||
|
||||
input:checked + label {
|
||||
border-color: if($is-dark-theme, white, var(--grey));
|
||||
|
||||
.cnsl-radio-header span {
|
||||
color: if($is-dark-theme, white, white);
|
||||
}
|
||||
}
|
||||
|
||||
.cnsl-radio-button {
|
||||
margin: .5rem;
|
||||
border-radius: .5rem;
|
||||
border: 1px solid if($is-dark-theme, var(--grey), white);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 0 1 230px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
padding-bottom: 1rem;
|
||||
box-shadow: inset 0 0 6px rgba(0, 0, 0, .1);
|
||||
|
||||
&.first {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&.last {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.recommended {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateY(50%) translateX(-50%);
|
||||
border-radius: 50vw;
|
||||
font-size: 11px;
|
||||
background: white;
|
||||
color: black;
|
||||
padding: 3px 1rem;
|
||||
box-shadow: 0 0 6px rgb(0 0 0 / 10%);
|
||||
white-space: nowrap;
|
||||
|
||||
&.not {
|
||||
background: rgb(144 75 75);
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.cnsl-radio-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
background: rgb(80, 110, 110);
|
||||
border-top-left-radius: 6px;
|
||||
border-top-right-radius: 6px;
|
||||
position: relative;
|
||||
|
||||
.current {
|
||||
position: absolute;
|
||||
bottom: .5rem;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: block;
|
||||
color: #ffffff60;
|
||||
white-space: nowrap;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
span {
|
||||
margin: 2rem;
|
||||
font-size: 30px;
|
||||
color: if($is-dark-theme,#21222450, #ffffff50);
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: center;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
.type-desc {
|
||||
font-size: 14px;
|
||||
color: var(--grey);
|
||||
}
|
||||
|
||||
.fill-space {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.app-specs {
|
||||
display: block;
|
||||
padding: 1rem 0;
|
||||
margin: 0 1rem;
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
color: var(--grey);
|
||||
margin: 3px 0;
|
||||
|
||||
span {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
:first-child {
|
||||
margin-right: 1rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { OIDCAuthMethodType, OIDCGrantType, OIDCResponseType } from 'src/app/proto/generated/management_pb';
|
||||
|
||||
export interface RadioItemAuthType {
|
||||
key: string;
|
||||
titleI18nKey: string;
|
||||
descI18nKey: string;
|
||||
disabled: boolean,
|
||||
prefix: string;
|
||||
background: string;
|
||||
responseType?: OIDCResponseType;
|
||||
grantType?: OIDCGrantType;
|
||||
authMethod?: OIDCAuthMethodType;
|
||||
recommended?: boolean;
|
||||
notRecommended?: boolean;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-auth-method-radio',
|
||||
templateUrl: './app-auth-method-radio.component.html',
|
||||
styleUrls: ['./app-auth-method-radio.component.scss'],
|
||||
})
|
||||
export class AppAuthMethodRadioComponent {
|
||||
@Input() current: string = '';
|
||||
@Input() selected: string = '';
|
||||
@Input() authMethods!: RadioItemAuthType[];
|
||||
@Output() selectedMethod: EventEmitter<string> = new EventEmitter();
|
||||
|
||||
public emitChange(): void {
|
||||
this.selectedMethod.emit(this.selected);
|
||||
}
|
||||
}
|
27
console/src/app/modules/app-radio/app-radio.module.ts
Normal file
27
console/src/app/modules/app-radio/app-radio.module.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MatRippleModule } from '@angular/material/core';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
import { AppAuthMethodRadioComponent } from './app-auth-method-radio/app-auth-method-radio.component';
|
||||
import { AppTypeRadioComponent } from './app-type-radio/app-type-radio.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppTypeRadioComponent,
|
||||
AppAuthMethodRadioComponent,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
MatRippleModule,
|
||||
TranslateModule,
|
||||
],
|
||||
exports: [
|
||||
AppAuthMethodRadioComponent,
|
||||
AppTypeRadioComponent,
|
||||
],
|
||||
})
|
||||
export class AppRadioModule { }
|
||||
|
@ -0,0 +1,14 @@
|
||||
<div class="radio-button-wrapper">
|
||||
<ng-container *ngFor="let type of types">
|
||||
<input type="radio" [disabled]="type.disabled" (change)="emitChange()" [value]="type.type"
|
||||
[(ngModel)]="selected" [id]="type.type" />
|
||||
<label class="cnsl-type-radio-button" [for]="type.type">
|
||||
<div class="cnsl-type-radio-header" [ngStyle]="{'background': type.background}">
|
||||
<span>{{type.prefix}}</span>
|
||||
</div>
|
||||
<p>{{type.titleI18nKey | translate}}</p>
|
||||
<p class="type-desc">{{type.descI18nKey | translate}}</p>
|
||||
<span class="fill-space"></span>
|
||||
</label>
|
||||
</ng-container>
|
||||
</div>
|
@ -0,0 +1,68 @@
|
||||
|
||||
@import '~@angular/material/theming';
|
||||
|
||||
.radio-button-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -0.5rem;
|
||||
}
|
||||
|
||||
@mixin app-type-radio-theme($theme) {
|
||||
$primary: map-get($theme, primary);
|
||||
$primary-color: mat-color($primary, 500);
|
||||
$is-dark-theme: map-get($theme, is-dark);
|
||||
|
||||
input[type="radio"]{
|
||||
appearance: none;
|
||||
opacity: 0;
|
||||
display: none;
|
||||
}
|
||||
|
||||
input:checked + label {
|
||||
border-color: if($is-dark-theme, white, var(--grey));
|
||||
|
||||
.cnsl-type-radio-header span {
|
||||
color: if($is-dark-theme, white, white);
|
||||
}
|
||||
}
|
||||
|
||||
.cnsl-type-radio-button {
|
||||
margin: .5rem;
|
||||
border-radius: .5rem;
|
||||
border: 1px solid if($is-dark-theme, var(--grey), white);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 0 1 240px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
padding-bottom: 1rem;
|
||||
box-shadow: inset 0 0 6px rgba(0, 0, 0, .1);
|
||||
|
||||
.cnsl-type-radio-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgb(80, 110, 110);
|
||||
margin-bottom: 1rem;
|
||||
border-top-left-radius: 6px;
|
||||
border-top-right-radius: 6px;
|
||||
|
||||
span {
|
||||
margin: 2rem;
|
||||
font-size: 30px;
|
||||
color: if($is-dark-theme,#21222450, #ffffff50);
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: center;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
.type-desc {
|
||||
font-size: 14px;
|
||||
color: var(--grey);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { OIDCApplicationType } from 'src/app/proto/generated/management_pb';
|
||||
|
||||
export interface RadioItemAppType {
|
||||
type: OIDCApplicationType;
|
||||
titleI18nKey: string;
|
||||
descI18nKey: string;
|
||||
checked: boolean,
|
||||
disabled: boolean,
|
||||
prefix: string;
|
||||
background: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-type-radio',
|
||||
templateUrl: './app-type-radio.component.html',
|
||||
styleUrls: ['./app-type-radio.component.scss'],
|
||||
})
|
||||
export class AppTypeRadioComponent {
|
||||
@Input() selected: OIDCApplicationType = OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB;
|
||||
@Input() types!: RadioItemAppType[];
|
||||
@Output() selectedType: EventEmitter<OIDCApplicationType> = new EventEmitter();
|
||||
|
||||
public emitChange(): void {
|
||||
this.selectedType.emit(this.selected);
|
||||
}
|
||||
}
|
@ -4,7 +4,8 @@
|
||||
<h2 class="title">{{title}}</h2>
|
||||
<span class="fill-space"></span>
|
||||
<ng-content select="[card-actions]"></ng-content>
|
||||
<button class="button" matTooltip="Expand or collapse" mat-icon-button (click)="expanded = !expanded">
|
||||
<button class="button" type="button" matTooltip="Expand or collapse" mat-icon-button
|
||||
(click)="expanded = !expanded">
|
||||
<mat-icon *ngIf="!expanded">keyboard_arrow_down</mat-icon>
|
||||
<mat-icon *ngIf="expanded">keyboard_arrow_up</mat-icon>
|
||||
</button>
|
||||
|
@ -24,6 +24,8 @@
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .05em;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fill-space {
|
||||
|
@ -18,7 +18,7 @@ import { Component, Input } from '@angular/core';
|
||||
],
|
||||
})
|
||||
export class CardComponent {
|
||||
public expanded: boolean = true;
|
||||
@Input() public expanded: boolean = true;
|
||||
@Input() public title: string = '';
|
||||
@Input() public description: string = '';
|
||||
@Input() public animate: boolean = false;
|
||||
|
@ -110,9 +110,9 @@ export class IdpCreateComponent implements OnInit, OnDestroy {
|
||||
setTimeout(() => {
|
||||
this.loading = false;
|
||||
this.router.navigate([
|
||||
this.serviceType === PolicyComponentServiceType.MGMT ? 'org' :
|
||||
this.serviceType === PolicyComponentServiceType.ADMIN ? 'iam' : '',
|
||||
'idp', idp.getId()]);
|
||||
(this.serviceType === PolicyComponentServiceType.MGMT ? 'org' :
|
||||
this.serviceType === PolicyComponentServiceType.ADMIN ? 'iam' : ''),
|
||||
'policy', 'login']);
|
||||
}, 2000);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
|
@ -1,6 +1,6 @@
|
||||
<app-refresh-table [loading]="loading$ | async" (refreshed)="refreshPage()" [dataSize]="dataSource.data.length"
|
||||
[emitRefreshOnPreviousRoutes]="['/iam/idp/create']" [timestamp]="idpResult?.viewTimestamp" [selection]="selection">
|
||||
<ng-template appHasRole [appHasRole]="['iam.write']" actions>
|
||||
<div actions>
|
||||
<button (click)="deactivateSelectedIdps()" matTooltip="{{'IDP.DEACTIVATE' | translate}}" class="icon-button"
|
||||
mat-icon-button *ngIf="selection.hasValue()" [disabled]="disabled">
|
||||
<mat-icon>block</mat-icon>
|
||||
@ -16,7 +16,7 @@
|
||||
<a [routerLink]="createRouterLink" color="primary" mat-raised-button [disabled]="disabled">
|
||||
<mat-icon class="icon">add</mat-icon>{{ 'ACTIONS.NEW' | translate }}
|
||||
</a>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
||||
<div class="table-wrapper">
|
||||
<table class="table" mat-table [dataSource]="dataSource">
|
||||
|
@ -1,5 +1,7 @@
|
||||
<div class="info-section-row">
|
||||
<i class="icon las la-info"></i>
|
||||
<div class="info-section-row" [ngClass]="{'info': type == 'INFO', 'warn': type == 'WARN'}">
|
||||
<i *ngIf="type == 'INFO'" class="icon las la-info"></i>
|
||||
<i *ngIf="type == 'WARN'" class="las la-exclamation"></i>
|
||||
|
||||
<div class="info-section-content">
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
|
@ -7,24 +7,36 @@
|
||||
|
||||
.info-section-row {
|
||||
display: flex;
|
||||
background-color: if($is-dark-theme, #ffffff13, #f3f3f3);
|
||||
border-radius: 4px;
|
||||
padding: .5rem 0;
|
||||
padding-right: 1rem;
|
||||
color: if($is-dark-theme, #d6d6d6, #3c4257);
|
||||
font-size: 14px;
|
||||
|
||||
.icon {
|
||||
margin-right: 1rem;
|
||||
height: 1.2rem;
|
||||
line-height: 1.2rem;
|
||||
font-size: 1.2rem;
|
||||
margin-left: .5rem;
|
||||
color: $primary-color;
|
||||
margin-right: 1rem;
|
||||
height: 1.2rem;
|
||||
line-height: 1.2rem;
|
||||
font-size: 1.2rem;
|
||||
margin-left: .5rem;
|
||||
}
|
||||
|
||||
|
||||
.info-section-content {
|
||||
flex: 1;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&.info {
|
||||
background-color: if($is-dark-theme, #4f566b, #cbf4c9);
|
||||
color: if($is-dark-theme, #cbf4c9, #0e6245);
|
||||
|
||||
.icon {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.warn {
|
||||
background-color: if($is-dark-theme, #4f566b, #ffc1c1);
|
||||
color: if($is-dark-theme, #ffc1c1, #620e0e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,16 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, Input } from '@angular/core';
|
||||
|
||||
enum InfoSectionType {
|
||||
INFO = 'INFO',
|
||||
WARN = 'WARN',
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-info-section',
|
||||
templateUrl: './info-section.component.html',
|
||||
styleUrls: ['./info-section.component.scss'],
|
||||
})
|
||||
export class InfoSectionComponent { }
|
||||
export class InfoSectionComponent {
|
||||
|
||||
@Input() type = InfoSectionType.INFO;
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { OnboardingComponent } from './onboarding.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: OnboardingComponent,
|
||||
data: { animation: 'AddPage' },
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class OnboardingRoutingModule { }
|
27
console/src/app/modules/onboarding/onboarding.component.html
Normal file
27
console/src/app/modules/onboarding/onboarding.component.html
Normal file
@ -0,0 +1,27 @@
|
||||
<div class="split">
|
||||
<div class="left">
|
||||
<p class="firststeps">{{'ONBOARDING.HEADER' | translate}}</p>
|
||||
<h1>{{'ONBOARDING.TITLE' | translate}}</h1>
|
||||
</div>
|
||||
<div class="right">
|
||||
<p class="desc">{{'ONBOARDING.DESCRIPTION' | translate}}</p>
|
||||
|
||||
<h2>{{'ONBOARDING.STEPS_TITLE' | translate}}</h2>
|
||||
<div class="onboarding-row" *ngFor="let step of steps; index as i">
|
||||
<div class="prev">{{i + 1}}</div>
|
||||
<div>
|
||||
<h3>{{step.titleI18nKey | translate}}</h3>
|
||||
<p>{{step.descI18nKey | translate}}</p>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
<div class="action-row">
|
||||
<a *ngIf="step?.docs" [href]="step.docs" alt="Zitadel Docs" target="_blank"
|
||||
class="goto docs">{{'ONBOARDING.DOCS' |
|
||||
translate}}
|
||||
<i class="las la-external-link-alt"></i>
|
||||
</a>
|
||||
<a *ngIf="step.link" class="goto" [routerLink]="step.link">{{'ONBOARDING.START' | translate}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
147
console/src/app/modules/onboarding/onboarding.component.scss
Normal file
147
console/src/app/modules/onboarding/onboarding.component.scss
Normal file
@ -0,0 +1,147 @@
|
||||
@import '~@angular/material/theming';
|
||||
|
||||
@mixin onboarding-theme($theme) {
|
||||
/* stylelint-disable */
|
||||
$primary: map-get($theme, primary);
|
||||
$primary-color: mat-color($primary, 500);
|
||||
$is-dark-theme: map-get($theme, is-dark);
|
||||
/* stylelint-enable */
|
||||
|
||||
.onboarding-row {
|
||||
box-shadow: inset 0 -1px if($is-dark-theme, #303131, #e3e8ee);
|
||||
|
||||
.prev {
|
||||
background: $primary-color;
|
||||
}
|
||||
|
||||
.goto {
|
||||
text-decoration: none;
|
||||
background: white;
|
||||
border: 1px solid if($is-dark-theme, #303131, #e3e8ee);
|
||||
|
||||
&.docs {
|
||||
background-color: $primary-color;
|
||||
|
||||
i {
|
||||
font-size: 1rem;
|
||||
margin-left: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.split {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 0 3px 8px 0 rgb(0 0 0 / 6%);
|
||||
|
||||
@media only screen and (min-width: 1024px) {
|
||||
flex-direction: row;
|
||||
|
||||
.right {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.left {
|
||||
flex-basis: 300px;
|
||||
box-sizing: border-box;
|
||||
padding: 1.5rem;
|
||||
background: linear-gradient(40deg, rgb(80, 66, 121),rgb(177, 59, 122),rgb(225,53,81), rgb(230,107,86));
|
||||
box-shadow: inset -2px 1px 15px -9px #000000;
|
||||
|
||||
h1 {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.firststeps {
|
||||
color: #fad6e3;
|
||||
text-transform: uppercase;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #fad6e3;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
padding: 1.5rem;
|
||||
flex: 1;
|
||||
box-sizing: border-box;
|
||||
|
||||
.desc {
|
||||
color: var(--grey);
|
||||
font-size: 20px;
|
||||
margin-top: .5rem;
|
||||
}
|
||||
|
||||
.onboarding-row {
|
||||
display: flex;
|
||||
padding: 1rem 0;
|
||||
align-items: center;
|
||||
|
||||
.prev {
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
min-width: 40px;
|
||||
border-radius: .5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 2rem;
|
||||
color: white;
|
||||
font-size: 1.2rem;
|
||||
box-shadow: 0 3px 8px 0 rgb(0 0 0 / 6%);
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: 0;
|
||||
margin-bottom: .5rem;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
color: var(--grey);
|
||||
}
|
||||
|
||||
.fill-space {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.action-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
|
||||
.goto {
|
||||
background-color: white;
|
||||
padding: 2px 1rem;
|
||||
color: black;
|
||||
border-radius: 50vw;
|
||||
font-size: 12px;
|
||||
margin: .5rem 0 .5rem 1rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { OnboardingComponent } from './onboarding.component';
|
||||
|
||||
describe('OnboardingComponent', () => {
|
||||
let component: OnboardingComponent;
|
||||
let fixture: ComponentFixture<OnboardingComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ OnboardingComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(OnboardingComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
16
console/src/app/modules/onboarding/onboarding.component.ts
Normal file
16
console/src/app/modules/onboarding/onboarding.component.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { AuthenticationService } from 'src/app/services/authentication.service';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-onboarding',
|
||||
templateUrl: './onboarding.component.html',
|
||||
styleUrls: ['./onboarding.component.scss']
|
||||
})
|
||||
export class OnboardingComponent {
|
||||
public steps = [
|
||||
{ titleI18nKey: 'ONBOARDING.STEPS.1.TITLE', descI18nKey: 'ONBOARDING.STEPS.1.DESC', docs: "https://docs.zitadel.ch/use", link: ['/projects', 'create'] },
|
||||
{ titleI18nKey: 'ONBOARDING.STEPS.2.TITLE', descI18nKey: 'ONBOARDING.STEPS.2.DESC', docs: "https://docs.zitadel.ch/use", link: ['/projects'] },
|
||||
{ titleI18nKey: 'ONBOARDING.STEPS.3.TITLE', descI18nKey: 'ONBOARDING.STEPS.3.DESC', link: ['/iam', 'policies'] },
|
||||
];
|
||||
constructor() { }
|
||||
}
|
18
console/src/app/modules/onboarding/onboarding.module.ts
Normal file
18
console/src/app/modules/onboarding/onboarding.module.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
import { OnboardingRoutingModule } from './onboarding-routing.module';
|
||||
import { OnboardingComponent } from './onboarding.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [OnboardingComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
TranslateModule,
|
||||
OnboardingRoutingModule,
|
||||
MatButtonModule,
|
||||
],
|
||||
})
|
||||
export class OnboardingModule { }
|
@ -73,14 +73,14 @@
|
||||
<p class="subdesc">{{ 'MFA.LIST.MULTIFACTORDESCRIPTION' | translate }}</p>
|
||||
<app-mfa-table [service]="service" [serviceType]="serviceType"
|
||||
[componentType]="LoginMethodComponentType.MultiFactor"
|
||||
[disabled]="([serviceType == PolicyComponentServiceType.ADMIN ? 'iam.policy.write' : serviceType == PolicyComponentServiceType.MGMT ? 'iam.policy.write' : ''] | hasRole | async) == false">
|
||||
[disabled]="([serviceType == PolicyComponentServiceType.ADMIN ? 'iam.policy.write' : serviceType == PolicyComponentServiceType.MGMT ? 'policy.write' : ''] | hasRole | async) == false">
|
||||
</app-mfa-table>
|
||||
|
||||
<h3 class="subheader">{{ 'MFA.LIST.SECONDFACTORTITLE' | translate }}</h3>
|
||||
<p class="subdesc">{{ 'MFA.LIST.SECONDFACTORDESCRIPTION' | translate }}</p>
|
||||
<app-mfa-table [service]="service" [serviceType]="serviceType"
|
||||
[componentType]="LoginMethodComponentType.SecondFactor"
|
||||
[disabled]="([serviceType == PolicyComponentServiceType.ADMIN ? 'iam.policy.write' : serviceType == PolicyComponentServiceType.MGMT ? 'iam.policy.write' : ''] | hasRole | async) == false">
|
||||
[disabled]="([serviceType == PolicyComponentServiceType.ADMIN ? 'iam.policy.write' : serviceType == PolicyComponentServiceType.MGMT ? 'policy.write' : ''] | hasRole | async) == false">
|
||||
</app-mfa-table>
|
||||
</ng-container>
|
||||
|
||||
|
@ -16,12 +16,42 @@
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<ng-template appHasRole [appHasRole]="['iam.write']">
|
||||
<a matRipple *ngIf="!firstStepsDismissed" class="onboard" [routerLink]="['/firststeps']">
|
||||
<p class="first-steps">{{'ONBOARDING.HEADER' | translate}}</p>
|
||||
<h2>{{'ONBOARDING.TITLE' | translate}}</h2>
|
||||
<p class="desc">{{'ONBOARDING.DESCRIPTION' | translate}}</p>
|
||||
<button matTooltip="{{'ACTIONS.CLOSE' | translate}}" (click)="dismissFirstSteps($event)" mat-icon-button
|
||||
class="close">
|
||||
<i class="las la-times"></i>
|
||||
</button>
|
||||
</a>
|
||||
</ng-template>
|
||||
|
||||
<a matRipple *ngIf="!firstStepsDismissed" class="quickstart" target="_blank"
|
||||
href="https://docs.zitadel.ch/quickstarts">
|
||||
<p class="first-steps">{{'HOME.QUICKSTARTS.LABEL' | translate}}</p>
|
||||
<h2>{{'HOME.QUICKSTARTS.TITLE' | translate}}</h2>
|
||||
<p class="desc">{{'HOME.QUICKSTARTS.DESCRIPTION' | translate}}</p>
|
||||
<div class="logo-cloud">
|
||||
<i class="lab la-angular"></i>
|
||||
<i class="lab la-react"></i>
|
||||
<i class="lab la-android"></i>
|
||||
<i class="lab la-app-store-ios"></i>
|
||||
</div>
|
||||
<button matTooltip="{{'ACTIONS.CLOSE' | translate}}" (click)="dismissQuickstarts($event)" mat-icon-button
|
||||
class="close">
|
||||
<i class="las la-times"></i>
|
||||
</button>
|
||||
</a>
|
||||
|
||||
<ng-template appHasRole [appHasRole]="['iam.write']">
|
||||
<app-card class="item">
|
||||
<div class="top">
|
||||
<h2>
|
||||
<i class="icon las la-gem"></i>
|
||||
{{'HOME.IAM'| translate}}</h2>
|
||||
{{'HOME.IAM'| translate}}
|
||||
</h2>
|
||||
<p>{{'HOME.IAM_DESC'| translate}}</p>
|
||||
</div>
|
||||
|
||||
@ -30,15 +60,12 @@
|
||||
class="las la-link"></i></a>
|
||||
</ng-template>
|
||||
<ng-template appHasRole [appHasRole]="['iam.policy.read']">
|
||||
<a class="short-link"
|
||||
[routerLink]="[ '/iam', 'policy','iam']">{{'HOME.IAM_POLICY_IAM' | translate}}<i
|
||||
class="las la-link"></i></a>
|
||||
<a class="short-link"
|
||||
[routerLink]="[ '/iam', 'policy','complexity']">{{'HOME.IAM_POLICY_COMPLEXITY' | translate}}<i
|
||||
class="las la-link"></i></a>
|
||||
<a class="short-link"
|
||||
[routerLink]="[ '/iam', 'policy','login']">{{'HOME.IAM_POLICY_LOGIN' | translate}}<i
|
||||
class="las la-link"></i></a>
|
||||
<a class="short-link" [routerLink]="[ '/iam', 'policy','iam']">{{'HOME.IAM_POLICY_IAM' |
|
||||
translate}}<i class="las la-link"></i></a>
|
||||
<a class="short-link" [routerLink]="[ '/iam', 'policy','complexity']">{{'HOME.IAM_POLICY_COMPLEXITY'
|
||||
| translate}}<i class="las la-link"></i></a>
|
||||
<a class="short-link" [routerLink]="[ '/iam', 'policy','login']">{{'HOME.IAM_POLICY_LOGIN' |
|
||||
translate}}<i class="las la-link"></i></a>
|
||||
</ng-template>
|
||||
|
||||
<span class="fill-space"></span>
|
||||
@ -59,8 +86,8 @@
|
||||
|
||||
<span class="fill-space"></span>
|
||||
<div class="footer">
|
||||
<a color="primary" mat-stroked-button
|
||||
[routerLink]="['/users/me']">{{'HOME.SECURITYANDPRIVACY_BUTTON' | translate}}</a>
|
||||
<a color="primary" mat-stroked-button [routerLink]="['/users/me']">{{'HOME.SECURITYANDPRIVACY_BUTTON' |
|
||||
translate}}</a>
|
||||
</div>
|
||||
</app-card>
|
||||
|
||||
@ -69,18 +96,18 @@
|
||||
<div class="top">
|
||||
<h2>
|
||||
<i class="icon las la-layer-group"></i>
|
||||
{{'HOME.PROJECTS'| translate}}</h2>
|
||||
{{'HOME.PROJECTS'| translate}}
|
||||
</h2>
|
||||
<p>{{'HOME.PROJECTS_DESC'| translate}}</p>
|
||||
<ng-template appHasRole [appHasRole]="['project.create']">
|
||||
<a class="short-link"
|
||||
[routerLink]="[ '/projects', 'create']">{{'HOME.PROJECTS_NEW_LINK' | translate}}<i
|
||||
class="las la-link"></i></a>
|
||||
<a class="short-link" [routerLink]="[ '/projects', 'create']">{{'HOME.PROJECTS_NEW_LINK' |
|
||||
translate}}<i class="las la-link"></i></a>
|
||||
</ng-template>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
<div class="footer">
|
||||
<a color="primary" mat-stroked-button
|
||||
[routerLink]="['/projects']">{{'HOME.PROJECTS_BUTTON' | translate}}</a>
|
||||
<a color="primary" mat-stroked-button [routerLink]="['/projects']">{{'HOME.PROJECTS_BUTTON' |
|
||||
translate}}</a>
|
||||
</div>
|
||||
</app-card>
|
||||
</ng-template>
|
||||
@ -92,23 +119,21 @@
|
||||
{{'HOME.PROTECTION'| translate}}</h2>
|
||||
<p>{{'HOME.PROTECTION_DESC'| translate}}</p>
|
||||
<ng-template appHasRole [appHasRole]="['iam.policy.read']">
|
||||
<a class="short-link"
|
||||
[routerLink]="[ '/org', 'policy','iam']">{{'HOME.ORG_POLICY_IAM' | translate}}<i
|
||||
class="las la-link"></i></a>
|
||||
<a class="short-link" [routerLink]="[ '/org', 'policy','iam']">{{'HOME.ORG_POLICY_IAM' |
|
||||
translate}}<i class="las la-link"></i></a>
|
||||
</ng-template>
|
||||
<ng-template appHasRole [appHasRole]="['policy.read']">
|
||||
<a class="short-link"
|
||||
[routerLink]="[ '/org', 'policy','complexity']">{{'HOME.ORG_POLICY_COMPLEXITY' | translate}}<i
|
||||
class="las la-link"></i></a>
|
||||
<a class="short-link"
|
||||
[routerLink]="[ '/org', 'policy','login']">{{'HOME.ORG_POLICY_LOGIN' | translate}}<i
|
||||
class="las la-link"></i></a>
|
||||
[routerLink]="[ '/org', 'policy','complexity']">{{'HOME.ORG_POLICY_COMPLEXITY' |
|
||||
translate}}<i class="las la-link"></i></a>
|
||||
<a class="short-link" [routerLink]="[ '/org', 'policy','login']">{{'HOME.ORG_POLICY_LOGIN' |
|
||||
translate}}<i class="las la-link"></i></a>
|
||||
</ng-template>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
<div class="footer">
|
||||
<a color="primary" mat-stroked-button
|
||||
[routerLink]="['/org']">{{'HOME.PROTECTION_BUTTON' | translate}}</a>
|
||||
<a color="primary" mat-stroked-button [routerLink]="['/org']">{{'HOME.PROTECTION_BUTTON' |
|
||||
translate}}</a>
|
||||
</div>
|
||||
</app-card>
|
||||
</ng-template>
|
||||
@ -118,15 +143,14 @@
|
||||
<div class="top">
|
||||
<h2>
|
||||
<i class="las la-users"></i>
|
||||
{{'HOME.USERS'| translate}}</h2>
|
||||
{{'HOME.USERS'| translate}}
|
||||
</h2>
|
||||
<p>{{'HOME.USERS_DESC'| translate}}</p>
|
||||
<ng-template appHasRole [appHasRole]="['user.read(:[0-9]*)?']">
|
||||
<a class="short-link"
|
||||
[routerLink]="[ '/users', 'list', 'humans']">{{'HOME.USERS_HUMANS' | translate}}<i
|
||||
class="las la-link"></i></a>
|
||||
<a class="short-link"
|
||||
[routerLink]="[ '/users', 'list', 'machines']">{{'HOME.USERS_MACHINES' | translate}}<i
|
||||
class="las la-link"></i></a>
|
||||
<a class="short-link" [routerLink]="[ '/users', 'list', 'humans']">{{'HOME.USERS_HUMANS' |
|
||||
translate}}<i class="las la-link"></i></a>
|
||||
<a class="short-link" [routerLink]="[ '/users', 'list', 'machines']">{{'HOME.USERS_MACHINES' |
|
||||
translate}}<i class="las la-link"></i></a>
|
||||
</ng-template>
|
||||
<ng-template appHasRole [appHasRole]="['user.read']">
|
||||
<a class="short-link" [routerLink]="[ '/users', 'create']">{{'HOME.USERS_CREATE' | translate}}<i
|
||||
@ -135,8 +159,8 @@
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
<div class="footer">
|
||||
<a color="primary" mat-stroked-button
|
||||
[routerLink]="['/users/list/humans']">{{'HOME.USERS_BUTTON' | translate}}</a>
|
||||
<a color="primary" mat-stroked-button [routerLink]="['/users/list/humans']">{{'HOME.USERS_BUTTON' |
|
||||
translate}}</a>
|
||||
</div>
|
||||
</app-card>
|
||||
</ng-template>
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
.wrapper {
|
||||
padding-bottom: 100px;
|
||||
position: relative;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
@ -31,6 +32,78 @@
|
||||
margin: -1rem;
|
||||
justify-content: space-evenly;
|
||||
|
||||
.onboard,
|
||||
.quickstart {
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
flex: 1 0 45%;
|
||||
position: relative;
|
||||
border-radius: 0.5rem;
|
||||
margin: 1rem;
|
||||
padding: 1.5rem;
|
||||
box-shadow: 0 3px 8px 0 rgb(0 0 0 / 6%);
|
||||
|
||||
h2 {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.first-steps {
|
||||
text-transform: uppercase;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.close {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
||||
i {
|
||||
color: white;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.close {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.onboard {
|
||||
background: linear-gradient(40deg, rgb(80, 66, 121),rgb(177, 59, 122),rgb(225,53,81), rgb(230,107,86));
|
||||
|
||||
p {
|
||||
color: #fad6e3;
|
||||
}
|
||||
}
|
||||
|
||||
.quickstart {
|
||||
background: linear-gradient(30deg, #2283a6,#6c8f59);
|
||||
|
||||
p {
|
||||
color: #d6f3fa;
|
||||
}
|
||||
|
||||
.logo-cloud {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: -0.5rem;
|
||||
|
||||
i {
|
||||
font-size: 40px;
|
||||
padding: .5rem;
|
||||
border: 1px solid #ffffff50;
|
||||
border-radius: .5rem;
|
||||
margin: 0.5rem;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
flex: 1 0 45%;
|
||||
margin: 0 1rem;
|
||||
|
@ -8,8 +8,26 @@ import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
})
|
||||
export class HomeComponent {
|
||||
public dark: boolean = true;
|
||||
public firstStepsDismissed: boolean = false;
|
||||
public quickstartsDismissed: boolean = false;
|
||||
|
||||
constructor(public authService: GrpcAuthService) {
|
||||
const theme = localStorage.getItem('theme');
|
||||
this.dark = theme === 'dark-theme' ? true : theme === 'light-theme' ? false : true;
|
||||
|
||||
this.firstStepsDismissed = localStorage.getItem('firstStartDismissed') == 'true' ? true : false;
|
||||
this.quickstartsDismissed = localStorage.getItem('quickstartsDismissed') == 'true' ? true : false;
|
||||
}
|
||||
|
||||
dismissFirstSteps(event: Event): void {
|
||||
event.preventDefault();
|
||||
localStorage.setItem('firstStartDismissed', 'true');
|
||||
this.firstStepsDismissed = true;
|
||||
}
|
||||
|
||||
dismissQuickstarts(event: Event): void {
|
||||
event.preventDefault();
|
||||
localStorage.setItem('quickstartsDismissed', 'true');
|
||||
this.firstStepsDismissed = true;
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,20 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatRippleModule } from '@angular/material/core';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
import { AvatarModule } from 'src/app/modules/avatar/avatar.module';
|
||||
import { CardModule } from 'src/app/modules/card/card.module';
|
||||
import { OnboardingModule } from 'src/app/modules/onboarding/onboarding.module';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
|
||||
import { HomeRoutingModule } from './home-routing.module';
|
||||
import { HomeComponent } from './home.component';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [HomeComponent],
|
||||
imports: [
|
||||
@ -24,9 +25,12 @@ import { HomeComponent } from './home.component';
|
||||
MatButtonModule,
|
||||
TranslateModule,
|
||||
AvatarModule,
|
||||
MatTooltipModule,
|
||||
SharedModule,
|
||||
MatProgressSpinnerModule,
|
||||
CardModule,
|
||||
MatRippleModule,
|
||||
OnboardingModule,
|
||||
],
|
||||
})
|
||||
export class HomeModule { }
|
||||
|
@ -23,18 +23,14 @@
|
||||
<p class="step-title">{{'APP.OIDC.TITLEFIRST' | translate}}</p>
|
||||
<cnsl-form-field appearance="outline" class="formfield">
|
||||
<cnsl-label>{{ 'APP.NAME' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="name" />
|
||||
<input cnslInput cdkFocusInitial formControlName="name" />
|
||||
<span cnsl-error *ngIf="name?.errors?.required">{{'PROJECT.APP.NAMEREQUIRED' | translate}}</span>
|
||||
</cnsl-form-field>
|
||||
|
||||
<p class="step-title">{{'APP.OIDC.TYPETITLE' | translate}}</p>
|
||||
<mat-radio-group color="primary" aria-labelledby="radio-group-label" class="radio-group"
|
||||
formControlName="applicationType">
|
||||
<mat-radio-button class="radio-button" *ngFor="let type of oidcAppTypes | keyvalue"
|
||||
[value]="type.value">
|
||||
<div>{{('APP.OIDC.APPTYPE'+type.key.toString()) | translate}}</div>
|
||||
</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
<app-type-radio [types]="oidcAppTypes" (selectedType)="changedAppType($event)"
|
||||
[selected]="applicationType?.value"></app-type-radio>
|
||||
<div class="actions">
|
||||
<button mat-raised-button [disabled]="firstFormGroup.invalid" color="primary"
|
||||
matStepperNext>{{'ACTIONS.CONTINUE' | translate}}</button>
|
||||
@ -42,37 +38,19 @@
|
||||
</form>
|
||||
</mat-step>
|
||||
|
||||
<mat-step [editable]="true"
|
||||
*ngIf="oidcApp.applicationType === OIDCApplicationType.OIDCAPPLICATIONTYPE_USER_AGENT">
|
||||
<ng-template matStepLabel>{{'APP.OIDC.RESPONSESECTION' | translate}}</ng-template>
|
||||
<div class="checkbox-container">
|
||||
<mat-checkbox class="checkbox" *ngFor="let responsetype of oidcResponseTypes"
|
||||
(change)="changeResponseType()" color="primary" [(ngModel)]="responsetype.checked"
|
||||
[disabled]="responsetype.disabled">
|
||||
{{'APP.OIDC.RESPONSE'+responsetype.type | translate}}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button mat-stroked-button color="primary" matStepperPrevious>{{'ACTIONS.BACK' | translate}}</button>
|
||||
<button mat-raised-button color="primary" matStepperNext>{{'ACTIONS.CONTINUE' | translate}}</button>
|
||||
</div>
|
||||
</mat-step>
|
||||
|
||||
<mat-step *ngIf="oidcApp.applicationType === OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB"
|
||||
<!-- skip for native applications -->
|
||||
<mat-step *ngIf="oidcApp.applicationType !== OIDCApplicationType.OIDCAPPLICATIONTYPE_NATIVE"
|
||||
[stepControl]="secondFormGroup" [editable]="true">
|
||||
<form [formGroup]="secondFormGroup">
|
||||
<ng-template matStepLabel>{{'APP.OIDC.AUTHMETHODSECTION' | translate}}</ng-template>
|
||||
|
||||
<mat-radio-group color="primary" aria-labelledby="example-radio-group-label" class="radio-group"
|
||||
formControlName="authMethodType">
|
||||
<mat-radio-button class="radio-button" *ngFor="let authmethod of oidcAuthMethodType"
|
||||
[disabled]="authmethod.disabled" [value]="authmethod.type">
|
||||
{{'APP.OIDC.AUTHMETHOD'+authmethod.type | translate}}
|
||||
</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<app-auth-method-radio [authMethods]="authMethods" [selected]="authMethod?.value"
|
||||
(selectedMethod)="changedAppAuthMethod($event)">
|
||||
</app-auth-method-radio>
|
||||
|
||||
<div class="actions">
|
||||
<button mat-stroked-button color="primary"
|
||||
matStepperPrevious>{{'ACTIONS.BACK' | translate}}</button>
|
||||
<button mat-stroked-button color="primary" matStepperPrevious>{{'ACTIONS.BACK' |
|
||||
translate}}</button>
|
||||
<button mat-raised-button color="primary" [disabled]="secondFormGroup.invalid"
|
||||
matStepperNext>{{'ACTIONS.CONTINUE' | translate}}</button>
|
||||
</div>
|
||||
@ -89,25 +67,10 @@
|
||||
<p class="step-description" *ngIf="oidcApp.applicationType === OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB">
|
||||
{{'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate}}</p>
|
||||
|
||||
<form class="chip-form" (ngSubmit)="addUri(redInput, 'REDIRECT')">
|
||||
<cnsl-form-field appearance="outline" class="full-width">
|
||||
<cnsl-label>{{ 'APP.OIDC.REDIRECT' | translate }}</cnsl-label>
|
||||
<input #redInput cnslInput placeholder="{{'APP.OIDC.COMMAORENTERSEPERATION' | translate}}"
|
||||
[formControl]="redirectControl">
|
||||
</cnsl-form-field>
|
||||
<button matTooltip="{{'ACTIONS.ADD' | translate}}" type="submit" mat-icon-button>
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</form>
|
||||
<mat-chip-list #chipRedirectList aria-label="uri selection">
|
||||
<mat-chip #redInput class="chip" *ngFor="let uri of oidcApp.redirectUrisList" selected removable
|
||||
[matTooltip]="!uri?.startsWith('https://') ? ('APP.OIDC.UNSECUREREDIRECT' | translate): ''"
|
||||
[color]="!uri?.startsWith('https://') ? 'warn': 'white'" (removed)="removeUri(uri, 'REDIRECT')">
|
||||
{{uri}} <mat-icon matChipRemove>cancel</mat-icon>
|
||||
</mat-chip>
|
||||
</mat-chip-list>
|
||||
|
||||
<p *ngIf="redirectControl.invalid" class="error">{{'APP.OIDC.REDIRECTNOTVALID' | translate}}</p>
|
||||
<cnsl-redirect-uris class="redirect-section" [canWrite]="true"
|
||||
(changedUris)="oidcApp.redirectUrisList = $event" [urisList]="oidcApp.redirectUrisList"
|
||||
title="{{ 'APP.OIDC.REDIRECT' | translate }}">
|
||||
</cnsl-redirect-uris>
|
||||
|
||||
<p class="step-title">{{'APP.OIDC.POSTREDIRECTTITLE' | translate}}</p>
|
||||
<p class="step-description"
|
||||
@ -117,26 +80,10 @@
|
||||
*ngIf="oidcApp.applicationType === OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB || oidcApp.applicationType === OIDCApplicationType.OIDCAPPLICATIONTYPE_USER_AGENT">
|
||||
{{'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate}}</p>
|
||||
|
||||
<form class="chip-form" (ngSubmit)="addUri(postInput, 'POSTREDIRECT')">
|
||||
<cnsl-form-field appearance="outline" class="full-width">
|
||||
<cnsl-label>{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}</cnsl-label>
|
||||
<input #postInput cnslInput placeholder="{{'APP.OIDC.COMMAORENTERSEPERATION' | translate}}"
|
||||
[formControl]="postRedirectControl">
|
||||
</cnsl-form-field>
|
||||
<button matTooltip="{{'ACTIONS.ADD' | translate}}" type="submit" mat-icon-button>
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</form>
|
||||
<mat-chip-list #chipPostRedirectList aria-label="uri selection">
|
||||
<mat-chip class="chip" *ngFor="let uri of oidcApp.postLogoutRedirectUrisList"
|
||||
[matTooltip]="!uri?.startsWith('https://') ? ('APP.OIDC.UNSECUREREDIRECT' | translate): ''"
|
||||
removable (removed)="removeUri(uri, 'POSTREDIRECT')" selected
|
||||
[color]="!uri?.startsWith('https://') ? 'warn': 'white'">
|
||||
{{uri}} <mat-icon matChipRemove>cancel</mat-icon>
|
||||
</mat-chip>
|
||||
</mat-chip-list>
|
||||
|
||||
<p *ngIf="postRedirectControl.invalid" class="error">{{'APP.OIDC.REDIRECTNOTVALID' | translate}}</p>
|
||||
<cnsl-redirect-uris class="redirect-section" [canWrite]="true"
|
||||
(changedUris)="oidcApp.postLogoutRedirectUrisList = $event"
|
||||
[urisList]="oidcApp.postLogoutRedirectUrisList" title="{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}">
|
||||
</cnsl-redirect-uris>
|
||||
|
||||
<div class="actions">
|
||||
<button mat-stroked-button color="primary" matStepperPrevious>{{'ACTIONS.BACK' | translate}}</button>
|
||||
@ -171,9 +118,8 @@
|
||||
<span class="right" *ngIf="oidcApp.grantTypesList?.length > 0">
|
||||
[<span *ngFor="let element of oidcApp.grantTypesList; index as i">
|
||||
{{'APP.OIDC.GRANT'+element | translate}}
|
||||
{{i < oidcApp.grantTypesList.length - 1 ? ', ': ''}}
|
||||
</span>]
|
||||
</span>
|
||||
{{i < oidcApp.grantTypesList.length - 1 ? ', ' : '' }} </span>]
|
||||
</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="left">
|
||||
@ -182,9 +128,8 @@
|
||||
<span class="right" *ngIf="oidcApp.responseTypesList?.length > 0">
|
||||
[<span *ngFor="let element of oidcApp.responseTypesList; index as i">
|
||||
{{('APP.OIDC.RESPONSE'+element | translate)}}
|
||||
{{i < oidcApp.responseTypesList.length - 1 ? ', ': ''}}
|
||||
</span>]
|
||||
</span>
|
||||
{{i < oidcApp.responseTypesList.length - 1 ? ', ' : '' }} </span>]
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
@ -205,9 +150,8 @@
|
||||
<span class="right" *ngIf="oidcApp.redirectUrisList?.length > 0">
|
||||
[<span *ngFor="let redirect of oidcApp.redirectUrisList; index as i">
|
||||
{{redirect}}
|
||||
{{i < oidcApp.redirectUrisList.length - 1 ? ', ': ''}}
|
||||
</span>]
|
||||
</span>
|
||||
{{i < oidcApp.redirectUrisList.length - 1 ? ', ' : '' }} </span>]
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
@ -217,15 +161,14 @@
|
||||
<span class="right" *ngIf="oidcApp.postLogoutRedirectUrisList?.length > 0">
|
||||
[<span *ngFor="let redirect of oidcApp.postLogoutRedirectUrisList; index as i">
|
||||
{{redirect}}
|
||||
{{i < oidcApp.postLogoutRedirectUrisList.length - 1 ? ', ': ''}}
|
||||
</span>]
|
||||
</span>
|
||||
{{i < oidcApp.postLogoutRedirectUrisList.length - 1 ? ', ' : '' }} </span>]
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<button mat-stroked-button color="primary" matStepperPrevious>{{'ACTIONS.BACK' | translate}}</button>
|
||||
<button mat-raised-button color="primary"
|
||||
(click)="saveOIDCApp()">{{'ACTIONS.CREATE' | translate}}</button>
|
||||
<button mat-raised-button color="primary" (click)="saveOIDCApp()">{{'ACTIONS.CREATE' |
|
||||
translate}}</button>
|
||||
</div>
|
||||
</mat-step>
|
||||
</mat-horizontal-stepper>
|
||||
@ -241,8 +184,8 @@
|
||||
<cnsl-form-field appearance="outline" class="formfield">
|
||||
<cnsl-label>{{ 'APP.OIDC.APPTYPE' | translate }}</cnsl-label>
|
||||
<mat-select formControlName="applicationType">
|
||||
<mat-option *ngFor="let type of oidcAppTypes" [value]="type">
|
||||
{{ 'APP.OIDC.APPTYPE'+type | translate }}
|
||||
<mat-option *ngFor="let type of oidcAppTypes" [value]="type.type">
|
||||
{{ 'APP.OIDC.APPTYPE'+type.type | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
@ -274,32 +217,18 @@
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field appearance="outline" class="formfield full-width">
|
||||
<cnsl-label>{{ 'APP.OIDC.REDIRECT' | translate }}</cnsl-label>
|
||||
<mat-chip-list #chipRedirectList aria-label="uri selection">
|
||||
<mat-chip class="chip" *ngFor="let uri of oidcApp.redirectUrisList" removable
|
||||
(removed)="removeUri(uri, 'REDIRECT')">
|
||||
{{uri}} <mat-icon matChipRemove>cancel</mat-icon>
|
||||
</mat-chip>
|
||||
<input cnslInput [matChipInputFor]="chipRedirectList"
|
||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="true"
|
||||
(matChipInputTokenEnd)="addUri($event, 'REDIRECT')">
|
||||
</mat-chip-list>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field appearance="outline" class="formfield full-width">
|
||||
<cnsl-label>{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}</cnsl-label>
|
||||
<mat-chip-list #chipPostRedirectList aria-label="uri selection">
|
||||
<mat-chip class="chip" *ngFor="let uri of oidcApp.postLogoutRedirectUrisList" removable
|
||||
(removed)="removeUri(uri, 'POSTREDIRECT')">
|
||||
{{uri}} <mat-icon matChipRemove>cancel</mat-icon>
|
||||
</mat-chip>
|
||||
<input cnslInput [matChipInputFor]="chipPostRedirectList"
|
||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes" [matChipInputAddOnBlur]="true"
|
||||
(matChipInputTokenEnd)="addUri($event, 'POSTREDIRECT')">
|
||||
</mat-chip-list>
|
||||
</cnsl-form-field>
|
||||
<div class="formfield full-width">
|
||||
<cnsl-redirect-uris class="redirect-section" [canWrite]="true"
|
||||
(changedUris)="oidcApp.redirectUrisList = $event" [urisList]="oidcApp.redirectUrisList"
|
||||
title="{{ 'APP.OIDC.REDIRECT' | translate }}">
|
||||
</cnsl-redirect-uris>
|
||||
|
||||
<cnsl-redirect-uris class="redirect-section" [canWrite]="true"
|
||||
(changedUris)="oidcApp.postLogoutRedirectUrisList = $event"
|
||||
[urisList]="oidcApp.postLogoutRedirectUrisList"
|
||||
title="{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}">
|
||||
</cnsl-redirect-uris>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button color="primary" mat-raised-button class="continue-button" [disabled]="form.invalid" cdkFocusInitial
|
||||
|
@ -42,11 +42,6 @@ p.desc {
|
||||
margin-right: .5rem;
|
||||
}
|
||||
|
||||
.formfield {
|
||||
width: 400px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.full-width {
|
||||
width: 100%;
|
||||
}
|
||||
@ -55,6 +50,10 @@ p.desc {
|
||||
background: inherit !important;
|
||||
margin: 0 -1.5rem;
|
||||
|
||||
.formfield {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.step-title {
|
||||
font-size: 1rem;
|
||||
text-transform: uppercase;
|
||||
@ -65,44 +64,6 @@ p.desc {
|
||||
font-size: .9rem;
|
||||
color: var(--grey);
|
||||
}
|
||||
|
||||
.chip-form {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.formfield {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.error {
|
||||
font-size: 13px;
|
||||
color: #f44336;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.chip {
|
||||
border-radius: 4px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.chip[color='white'] {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
}
|
||||
|
||||
.radio-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.radio-button {
|
||||
margin: .5rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
.checkbox-container {
|
||||
@ -137,7 +98,6 @@ p.desc {
|
||||
float: right;
|
||||
margin-top: 1rem;
|
||||
border-radius: .5rem;
|
||||
padding: .5rem 1rem;
|
||||
min-width: 100px;
|
||||
}
|
||||
}
|
||||
@ -147,9 +107,11 @@ p.desc {
|
||||
display: flex;
|
||||
margin: 0 -.5rem;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
|
||||
.formfield {
|
||||
flex: 1 0 40%;
|
||||
flex: 1;
|
||||
box-sizing: border-box;
|
||||
margin: 0 .5rem;
|
||||
|
||||
&.full-width {
|
||||
@ -164,4 +126,4 @@ p.desc {
|
||||
padding: .5rem 4rem;
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import { MatDialog } from '@angular/material/dialog';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { debounceTime } from 'rxjs/operators';
|
||||
import { RadioItemAuthType } from 'src/app/modules/app-radio/app-auth-method-radio/app-auth-method-radio.component';
|
||||
import {
|
||||
Application,
|
||||
OIDCApplicationCreate,
|
||||
@ -17,7 +18,15 @@ import {
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
|
||||
import {
|
||||
WEB_TYPE,
|
||||
NATIVE_TYPE,
|
||||
USER_AGENT_TYPE
|
||||
} from '../authtypes';
|
||||
|
||||
import { AppSecretDialogComponent } from '../app-secret-dialog/app-secret-dialog.component';
|
||||
import { CODE_METHOD, getPartialConfigFromAuthMethod, IMPLICIT_METHOD, PKCE_METHOD, PK_JWT_METHOD, POST_METHOD } from '../authmethods';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-app-create',
|
||||
@ -37,10 +46,16 @@ export class AppCreateComponent implements OnInit, OnDestroy {
|
||||
{ type: OIDCResponseType.OIDCRESPONSETYPE_ID_TOKEN_TOKEN, checked: false, disabled: false },
|
||||
];
|
||||
|
||||
public oidcAppTypes: OIDCApplicationType[] = [
|
||||
OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB,
|
||||
OIDCApplicationType.OIDCAPPLICATIONTYPE_USER_AGENT,
|
||||
OIDCApplicationType.OIDCAPPLICATIONTYPE_NATIVE,
|
||||
public oidcAppTypes: any = [
|
||||
WEB_TYPE,
|
||||
NATIVE_TYPE,
|
||||
USER_AGENT_TYPE,
|
||||
];
|
||||
|
||||
public authMethods: RadioItemAuthType[] = [
|
||||
PKCE_METHOD,
|
||||
CODE_METHOD,
|
||||
POST_METHOD,
|
||||
];
|
||||
|
||||
public oidcAuthMethodType: { type: OIDCAuthMethodType, checked: boolean, disabled: boolean; }[] = [
|
||||
@ -52,7 +67,6 @@ export class AppCreateComponent implements OnInit, OnDestroy {
|
||||
// stepper
|
||||
firstFormGroup!: FormGroup;
|
||||
secondFormGroup!: FormGroup;
|
||||
// thirdFormGroup!: FormGroup;
|
||||
|
||||
// devmode
|
||||
public form!: FormGroup;
|
||||
@ -72,9 +86,6 @@ export class AppCreateComponent implements OnInit, OnDestroy {
|
||||
// TODO show when implemented
|
||||
];
|
||||
|
||||
public redirectControl: FormControl = new FormControl('');
|
||||
public postRedirectControl: FormControl = new FormControl('');
|
||||
|
||||
public readonly separatorKeysCodes: number[] = [ENTER, COMMA, SPACE];
|
||||
|
||||
constructor(
|
||||
@ -104,64 +115,58 @@ export class AppCreateComponent implements OnInit, OnDestroy {
|
||||
|
||||
this.firstFormGroup = this.fb.group({
|
||||
name: ['', [Validators.required]],
|
||||
applicationType: ['', [Validators.required]],
|
||||
applicationType: [OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB, [Validators.required]],
|
||||
});
|
||||
|
||||
this.firstFormGroup.valueChanges.subscribe(value => {
|
||||
if (this.firstFormGroup.valid) {
|
||||
switch (value.applicationType) {
|
||||
case OIDCApplicationType.OIDCAPPLICATIONTYPE_NATIVE:
|
||||
this.oidcResponseTypes[0].checked = true;
|
||||
this.oidcApp.responseTypesList = [OIDCResponseType.OIDCRESPONSETYPE_CODE];
|
||||
|
||||
this.oidcApp.grantTypesList =
|
||||
[OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE];
|
||||
this.oidcApp.authMethodType = OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE;
|
||||
|
||||
// this.redirectControl = new FormControl('', [nativeValidator as ValidatorFn]);
|
||||
// this.postRedirectControl = new FormControl('', [nativeValidator as ValidatorFn]);
|
||||
break;
|
||||
case OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB:
|
||||
this.oidcAuthMethodType[0].disabled = false;
|
||||
this.oidcAuthMethodType[1].disabled = false;
|
||||
this.oidcAuthMethodType[2].disabled = false;
|
||||
this.authMethodType?.setValue(OIDCAuthMethodType.OIDCAUTHMETHODTYPE_BASIC);
|
||||
this.oidcApp.authMethodType = OIDCAuthMethodType.OIDCAUTHMETHODTYPE_BASIC;
|
||||
|
||||
this.oidcResponseTypes[0].checked = true;
|
||||
this.oidcApp.responseTypesList = [OIDCResponseType.OIDCRESPONSETYPE_CODE];
|
||||
this.changeResponseType();
|
||||
|
||||
this.oidcApp.grantTypesList =
|
||||
[OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE];
|
||||
|
||||
// this.redirectControl = new FormControl('', [webValidator as ValidatorFn]);
|
||||
// this.postRedirectControl = new FormControl('', [webValidator as ValidatorFn]);
|
||||
break;
|
||||
case OIDCApplicationType.OIDCAPPLICATIONTYPE_USER_AGENT:
|
||||
this.oidcResponseTypes[0].checked = true;
|
||||
this.oidcApp.responseTypesList = [OIDCResponseType.OIDCRESPONSETYPE_CODE];
|
||||
|
||||
this.oidcApp.grantTypesList =
|
||||
[OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE, OIDCGrantType.OIDCGRANTTYPE_IMPLICIT];
|
||||
|
||||
this.oidcApp.authMethodType = OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE;
|
||||
|
||||
// this.redirectControl = new FormControl('', [webValidator as ValidatorFn]);
|
||||
// this.postRedirectControl = new FormControl('', [webValidator as ValidatorFn]);
|
||||
break;
|
||||
}
|
||||
|
||||
this.oidcApp.name = this.name?.value;
|
||||
this.oidcApp.applicationType = this.applicationType?.value;
|
||||
|
||||
switch (this.applicationType?.value) {
|
||||
case OIDCApplicationType.OIDCAPPLICATIONTYPE_NATIVE:
|
||||
this.authMethods = [
|
||||
PKCE_METHOD,
|
||||
];
|
||||
|
||||
// automatically set to PKCE and skip step
|
||||
this.oidcApp.responseTypesList = [OIDCResponseType.OIDCRESPONSETYPE_CODE];
|
||||
this.oidcApp.grantTypesList = [OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE];
|
||||
this.oidcApp.authMethodType = OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE;
|
||||
|
||||
break;
|
||||
case OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB:
|
||||
this.authMethods = [
|
||||
PKCE_METHOD,
|
||||
CODE_METHOD,
|
||||
POST_METHOD,
|
||||
];
|
||||
|
||||
this.authMethod?.setValue(PKCE_METHOD.key);
|
||||
break;
|
||||
case OIDCApplicationType.OIDCAPPLICATIONTYPE_USER_AGENT:
|
||||
this.authMethods = [
|
||||
PKCE_METHOD,
|
||||
IMPLICIT_METHOD,
|
||||
];
|
||||
|
||||
this.authMethod?.setValue(PKCE_METHOD.key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.secondFormGroup = this.fb.group({
|
||||
authMethodType: [OIDCAuthMethodType.OIDCAUTHMETHODTYPE_BASIC, [Validators.required]],
|
||||
authMethod: [this.authMethods[0].key, [Validators.required]],
|
||||
});
|
||||
this.secondFormGroup.valueChanges.subscribe(value => {
|
||||
this.oidcApp.authMethodType = value.authMethodType;
|
||||
this.secondFormGroup.valueChanges.subscribe(form => {
|
||||
const partialConfig = getPartialConfigFromAuthMethod(form.authMethod);
|
||||
|
||||
if (partialConfig) {
|
||||
this.oidcApp.responseTypesList = partialConfig.responseTypesList ?? [];
|
||||
this.oidcApp.grantTypesList = partialConfig.grantTypesList ?? [];
|
||||
this.oidcApp.authMethodType = partialConfig.authMethodType ?? OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -173,6 +178,15 @@ export class AppCreateComponent implements OnInit, OnDestroy {
|
||||
this.subscription?.unsubscribe();
|
||||
}
|
||||
|
||||
public changedAppType(type: OIDCApplicationType) {
|
||||
this.firstFormGroup.controls['applicationType'].setValue(type);
|
||||
}
|
||||
|
||||
public changedAppAuthMethod(methodKey: string) {
|
||||
console.log(methodKey);
|
||||
this.secondFormGroup.controls['authMethod'].setValue(methodKey);
|
||||
}
|
||||
|
||||
private async getData({ projectid }: Params): Promise<void> {
|
||||
this.projectId = projectid;
|
||||
this.oidcApp.projectId = projectid;
|
||||
@ -215,66 +229,20 @@ export class AppCreateComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
public addUri(input: any, target: string): void {
|
||||
const value = input.value.trim();
|
||||
|
||||
if (value !== '') {
|
||||
if (target === 'REDIRECT' && this.redirectControl.valid) {
|
||||
this.oidcApp.redirectUrisList.push(value);
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
} else if (target === 'POSTREDIRECT' && this.redirectControl.valid) {
|
||||
this.oidcApp.postLogoutRedirectUrisList.push(value);
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public removeUri(uri: string, target: string): void {
|
||||
if (target === 'REDIRECT') {
|
||||
const index = this.oidcApp.redirectUrisList.indexOf(uri);
|
||||
|
||||
if (index !== undefined && index >= 0) {
|
||||
this.oidcApp.redirectUrisList.splice(index, 1);
|
||||
}
|
||||
} else if (target === 'POSTREDIRECT') {
|
||||
const index = this.oidcApp.postLogoutRedirectUrisList.indexOf(uri);
|
||||
|
||||
if (index !== undefined && index >= 0) {
|
||||
this.oidcApp.postLogoutRedirectUrisList.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
changeResponseType(): void {
|
||||
this.oidcApp.responseTypesList = this.oidcResponseTypes.filter(gt => gt.checked).map(gt => gt.type);
|
||||
}
|
||||
|
||||
moreThanOneOption(options: Array<{ type: OIDCGrantType, checked: boolean, disabled: boolean; }>): boolean {
|
||||
return options.filter(option => option.disabled === false).length > 1;
|
||||
}
|
||||
|
||||
get name(): AbstractControl | null {
|
||||
return this.firstFormGroup.get('name');
|
||||
}
|
||||
|
||||
get applicationType(): AbstractControl | null {
|
||||
return this.firstFormGroup.get('applicationType');
|
||||
}
|
||||
|
||||
public grantTypeChecked(type: OIDCGrantType): boolean {
|
||||
return this.oidcGrantTypes.filter(gt => gt.checked).map(gt => gt.type).findIndex(t => t === type) > -1;
|
||||
}
|
||||
|
||||
get responseTypesList(): AbstractControl | null {
|
||||
return this.secondFormGroup.get('responseTypesList');
|
||||
}
|
||||
|
||||
get authMethodType(): AbstractControl | null {
|
||||
return this.secondFormGroup.get('authMethodType');
|
||||
get authMethod(): AbstractControl | null {
|
||||
return this.secondFormGroup.get('authMethod');
|
||||
}
|
||||
|
||||
// devmode
|
||||
@ -282,24 +250,17 @@ export class AppCreateComponent implements OnInit, OnDestroy {
|
||||
get formname(): AbstractControl | null {
|
||||
return this.form.get('name');
|
||||
}
|
||||
|
||||
|
||||
get formresponseTypesList(): AbstractControl | null {
|
||||
return this.form.get('responseTypesList');
|
||||
}
|
||||
|
||||
|
||||
get formgrantTypesList(): AbstractControl | null {
|
||||
return this.form.get('grantTypesList');
|
||||
}
|
||||
|
||||
|
||||
get formapplicationType(): AbstractControl | null {
|
||||
return this.form.get('applicationType');
|
||||
}
|
||||
|
||||
get formauthMethodType(): AbstractControl | null {
|
||||
return this.form.get('authMethodType');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,10 +1,32 @@
|
||||
<app-meta-layout>
|
||||
<div class="max-width-container">
|
||||
<div class="enlarged-container">
|
||||
<div class="head">
|
||||
<a [routerLink]="['/projects', projectId]" mat-icon-button>
|
||||
<mat-icon class="icon">arrow_back</mat-icon>
|
||||
</a>
|
||||
<h1>{{ 'APP.PAGES.TITLE' | translate }} {{app?.name}}</h1>
|
||||
<div class="title-col">
|
||||
<h1>{{app?.name}}</h1>
|
||||
<span>{{'APP.OIDC.APPTYPE'+app?.oidcConfig?.applicationType | translate}}</span>
|
||||
</div>
|
||||
<ng-container *ngIf="isZitadel === false">
|
||||
<ng-template appHasRole [appHasRole]="['project.app.write:'+projectId, 'project.app.write']">
|
||||
<button *ngIf="!editState" matTooltip="{{'ACTIONS.EDIT' | translate}}" mat-icon-button
|
||||
(click)="editState = !editState" aria-label="edit app name">
|
||||
<i class="las la-edit"></i>
|
||||
</button>
|
||||
<button *ngIf="editState" (click)="saveApp()" [disabled]="appNameForm.invalid || name?.disabled"
|
||||
mat-icon-button>
|
||||
<i class="las la-save"></i>
|
||||
</button>
|
||||
</ng-template>
|
||||
|
||||
<ng-template appHasRole [appHasRole]="['project.app.delete:'+projectId, 'project.app.delete']">
|
||||
<button matTooltip="{{'ACTIONS.DELETE' | translate}}" color="warn" mat-icon-button
|
||||
(click)="deleteApp()" aria-label="delete app">
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
|
||||
<p class="desc">{{ 'APP.PAGES.DESCRIPTION' | translate }}</p>
|
||||
<p *ngIf="isZitadel" class="zitadel-warning">{{'PROJECT.PAGES.ZITADELPROJECT' | translate}}</p>
|
||||
@ -12,52 +34,85 @@
|
||||
|
||||
<span *ngIf="errorMessage" class="err-container">{{errorMessage}}</span>
|
||||
|
||||
<app-card title="{{ 'APP.PAGES.DETAIL.TITLE' | translate }}" *ngIf="app">
|
||||
<form [formGroup]="appNameForm" (ngSubmit)="saveApp()">
|
||||
<div class="name-content">
|
||||
<mat-button-toggle-group formControlName="state" class="toggle" (change)="changeState($event)">
|
||||
<mat-button-toggle [value]="AppState.APPSTATE_INACTIVE"
|
||||
matTooltip="{{ 'ACTIONS.DEACTIVATE' | translate}}">
|
||||
{{'APP.PAGES.DETAIL.STATE.'+AppState.APPSTATE_INACTIVE | translate}}
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="AppState.APPSTATE_ACTIVE"
|
||||
matTooltip="{{ 'ACTIONS.REACTIVATE' | translate}}">
|
||||
{{'APP.PAGES.DETAIL.STATE.'+AppState.APPSTATE_ACTIVE | translate}}
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
<form *ngIf="app && editState" [formGroup]="appNameForm">
|
||||
<div class="name-content">
|
||||
<mat-button-toggle-group formControlName="state" class="toggle" (change)="changeState($event)">
|
||||
<mat-button-toggle [value]="AppState.APPSTATE_INACTIVE"
|
||||
matTooltip="{{ 'ACTIONS.DEACTIVATE' | translate}}">
|
||||
{{'APP.PAGES.DETAIL.STATE.'+AppState.APPSTATE_INACTIVE | translate}}
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="AppState.APPSTATE_ACTIVE"
|
||||
matTooltip="{{ 'ACTIONS.REACTIVATE' | translate}}">
|
||||
{{'APP.PAGES.DETAIL.STATE.'+AppState.APPSTATE_ACTIVE | translate}}
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
|
||||
<cnsl-form-field class="name-field">
|
||||
<cnsl-label>{{ 'APP.NAME' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="name" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-info-section class="docs-line" *ngIf="docs?.discoveryEndpoint">
|
||||
<p><strong>Discovery Endpoint:</strong> {{docs.discoveryEndpoint}}</p>
|
||||
<p><strong>Issuer:</strong> {{docs.issuer}}</p>
|
||||
</cnsl-info-section>
|
||||
</div>
|
||||
<div class="btn-container">
|
||||
<button type="submit" color="primary" [disabled]="appNameForm.invalid || name?.disabled"
|
||||
mat-raised-button>{{ 'ACTIONS.SAVE' | translate }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</app-card>
|
||||
|
||||
<app-card title="{{ 'APP.OIDC.TITLE' | translate }}" *ngIf="app && app.oidcConfig">
|
||||
<div card-actions *ngIf="app?.oidcConfig?.authMethodType !== OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE">
|
||||
<button [disabled]="!canWrite" mat-stroked-button
|
||||
(click)="regenerateOIDCClientSecret()">{{'APP.OIDC.REGENERATESECRET' | translate}}</button>
|
||||
<cnsl-form-field class="name-field">
|
||||
<cnsl-label>{{ 'APP.NAME' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="name" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- <cnsl-info-section class="docs-line" *ngIf="docs?.discoveryEndpoint">
|
||||
<p><strong>Discovery Endpoint:</strong> {{docs.discoveryEndpoint}}</p>
|
||||
<p><strong>Issuer:</strong> {{docs.issuer}}</p>
|
||||
</cnsl-info-section> -->
|
||||
|
||||
<div class="compliance"
|
||||
*ngIf="app?.oidcConfig?.complianceProblemsList && app.oidcConfig?.complianceProblemsList?.length">
|
||||
<cnsl-info-section class="problem" type="WARN">
|
||||
<ul style="margin: 0;">
|
||||
<li style="margin: 0 0 .5rem 0;"
|
||||
*ngFor="let problem of app.oidcConfig?.complianceProblemsList || []">
|
||||
{{problem.localizedMessage}}</li>
|
||||
</ul>
|
||||
</cnsl-info-section>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<h3 class="full-width section-title">{{'APP.OIDC.REDIRECTSECTIONTITLE' | translate}}</h3>
|
||||
|
||||
<mat-slide-toggle color="primary" class="devmode" [formControl]="devMode" name="devMode"
|
||||
matTooltip="{{'APP.OIDC.DEVMODEDESC' | translate}}">
|
||||
{{ 'APP.OIDC.DEVMODE' | translate }}
|
||||
</mat-slide-toggle>
|
||||
|
||||
<cnsl-info-section class="step-description"
|
||||
*ngIf="applicationType?.value == OIDCApplicationType.OIDCAPPLICATIONTYPE_NATIVE">
|
||||
<span>{{'APP.OIDC.REDIRECTDESCRIPTIONNATIVE' | translate}}</span>
|
||||
</cnsl-info-section>
|
||||
|
||||
<p class="step-description"
|
||||
*ngIf="applicationType?.value == OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB || applicationType?.value == OIDCApplicationType.OIDCAPPLICATIONTYPE_USER_AGENT">
|
||||
{{'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate}}</p>
|
||||
|
||||
<div style="margin: .5rem" class="divider"></div>
|
||||
|
||||
<cnsl-redirect-uris class="redirect-section" [canWrite]="canWrite" [devMode]="devMode?.value"
|
||||
(changedUris)="redirectUrisList = $event" [urisList]="redirectUrisList"
|
||||
title="{{ 'APP.OIDC.REDIRECT' | translate }}">
|
||||
</cnsl-redirect-uris>
|
||||
|
||||
<cnsl-redirect-uris class="redirect-section" [canWrite]="canWrite" [devMode]="devMode?.value"
|
||||
(changedUris)="postLogoutRedirectUrisList = $event" [urisList]="postLogoutRedirectUrisList"
|
||||
title="{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}">
|
||||
</cnsl-redirect-uris>
|
||||
</div>
|
||||
|
||||
<app-auth-method-radio *ngIf="authMethods && initialAuthMethod && app?.oidcConfig" [authMethods]="authMethods"
|
||||
[selected]="initialAuthMethod" [current]="currentAuthMethod"
|
||||
(selectedMethod)="setPartialConfigFromAuthMethod($event)">
|
||||
</app-auth-method-radio>
|
||||
|
||||
<form *ngIf="appForm" [formGroup]="appForm" (ngSubmit)="saveOIDCApp()">
|
||||
<app-card title=" {{ 'APP.OIDC.TITLE' | translate }}" *ngIf="app && app.oidcConfig" [expanded]="false">
|
||||
<div card-actions
|
||||
*ngIf="app?.oidcConfig?.authMethodType !== OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE">
|
||||
<button [disabled]="!canWrite" mat-stroked-button
|
||||
(click)="regenerateOIDCClientSecret()">{{'APP.OIDC.REGENERATESECRET' | translate}}</button>
|
||||
</div>
|
||||
|
||||
<div class="compliance">
|
||||
<cnsl-info-section class="problem">
|
||||
<ul style="margin: 0;">
|
||||
<li style="margin: 0 0 .5rem 0;" *ngFor="let problem of app.oidcConfig.complianceProblemsList">
|
||||
{{problem.localizedMessage}}</li>
|
||||
</ul>
|
||||
</cnsl-info-section>
|
||||
</div>
|
||||
<form *ngIf="appForm" [formGroup]="appForm" (ngSubmit)="saveOIDCApp()">
|
||||
<div class="content">
|
||||
<cnsl-form-field class="formfield" appearance="outline">
|
||||
<cnsl-label>{{ 'APP.OIDC.CLIENTID' | translate }}</cnsl-label>
|
||||
@ -141,89 +196,46 @@
|
||||
<cnsl-info-section class="full-width desc">
|
||||
<span>{{'APP.OIDC.CLOCKSKEW' | translate}}</span>
|
||||
</cnsl-info-section>
|
||||
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<p class="full-width section-title">{{'APP.OIDC.REDIRECTSECTIONTITLE' | translate}}</p>
|
||||
|
||||
<mat-slide-toggle color="primary" class="devmode" formControlName="devMode" name="devMode">
|
||||
{{ 'APP.OIDC.DEVMODE' | translate }}
|
||||
</mat-slide-toggle>
|
||||
|
||||
<cnsl-info-section class="step-description">
|
||||
<span style="margin-bottom: 2rem;">{{'APP.OIDC.DEVMODEDESC' | translate}}</span>
|
||||
</cnsl-info-section>
|
||||
|
||||
<cnsl-info-section class="step-description"
|
||||
*ngIf="applicationType?.value == OIDCApplicationType.OIDCAPPLICATIONTYPE_NATIVE">
|
||||
<span>{{'APP.OIDC.REDIRECTDESCRIPTIONNATIVE' | translate}}</span>
|
||||
</cnsl-info-section>
|
||||
|
||||
<p class="step-description"
|
||||
*ngIf="applicationType?.value == OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB || applicationType?.value == OIDCApplicationType.OIDCAPPLICATIONTYPE_USER_AGENT">
|
||||
{{'APP.OIDC.REDIRECTDESCRIPTIONWEB' | translate}}</p>
|
||||
|
||||
<form class="chip-form" (ngSubmit)="add(redInput, RedirectType.REDIRECT)">
|
||||
<cnsl-form-field class="formfield full-width">
|
||||
<cnsl-label>{{ 'APP.OIDC.REDIRECT' | translate }}</cnsl-label>
|
||||
|
||||
<input #redInput cnslInput placeholder="{{'APP.OIDC.COMMAORENTERSEPERATION' | translate}}"
|
||||
[formControl]="redirectControl">
|
||||
</cnsl-form-field>
|
||||
<button matTooltip="{{'ACTIONS.ADD' | translate}}" type="submit" mat-icon-button
|
||||
[disabled]="redirectControl.invalid || !canWrite">
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</form>
|
||||
<mat-chip-list class="chiplist formfield full-width" [disabled]="!canWrite" #chipRedirectList>
|
||||
<mat-chip class="chip" *ngFor="let redirect of redirectUrisList" selected
|
||||
[matTooltip]="!redirect?.startsWith('https://') ? ('APP.OIDC.UNSECUREREDIRECT' | translate): ''"
|
||||
[color]="!redirect?.startsWith('https://') ? 'warn': 'green'"
|
||||
(removed)="remove(redirect, RedirectType.REDIRECT)">
|
||||
{{redirect}}
|
||||
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
|
||||
</mat-chip>
|
||||
</mat-chip-list>
|
||||
|
||||
<p *ngIf="redirectControl.value && redirectControl.invalid" class="error">
|
||||
{{'APP.OIDC.REDIRECTNOTVALID' | translate}}</p>
|
||||
|
||||
<form class="chip-form" (ngSubmit)="add(postInput, RedirectType.POSTREDIRECT)">
|
||||
<cnsl-form-field class="formfield full-width">
|
||||
<cnsl-label>{{ 'APP.OIDC.POSTLOGOUTREDIRECT' | translate }}</cnsl-label>
|
||||
<input #postInput cnslInput placeholder="{{'APP.OIDC.COMMAORENTERSEPERATION' | translate}}"
|
||||
[formControl]="postRedirectControl">
|
||||
</cnsl-form-field>
|
||||
<button matTooltip="{{'ACTIONS.ADD' | translate}}" type="submit" mat-icon-button
|
||||
[disabled]="postRedirectControl.invalid || !canWrite">
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</form>
|
||||
<mat-chip-list class="chiplist formfield full-width" [disabled]="!canWrite" #chipPostRedirectList>
|
||||
<mat-chip class="chip" *ngFor="let redirect of postLogoutRedirectUrisList" selected
|
||||
(removed)="remove(redirect, RedirectType.POSTREDIRECT)"
|
||||
[matTooltip]="!redirect?.startsWith('https://') ? ('APP.OIDC.UNSECUREREDIRECT' | translate): ''"
|
||||
[color]="!redirect?.startsWith('https://') ? 'warn': 'green'">
|
||||
{{redirect}}
|
||||
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
|
||||
</mat-chip>
|
||||
</mat-chip-list>
|
||||
|
||||
<p *ngIf="postRedirectControl.value && postRedirectControl.invalid" class="error">
|
||||
{{'APP.OIDC.REDIRECTNOTVALID' | translate}}</p>
|
||||
</div>
|
||||
<div class="btn-container">
|
||||
</app-card>
|
||||
|
||||
<button class="submit-button" type="submit" color="primary"
|
||||
[disabled]="appForm.invalid || !canWrite"
|
||||
mat-raised-button>{{ 'ACTIONS.SAVE' | translate }}</button>
|
||||
<div class="btn-container">
|
||||
<button class="submit-button" type="submit" color="primary" [disabled]="appForm.invalid || !canWrite"
|
||||
mat-raised-button>
|
||||
{{ 'ACTIONS.SAVE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="next-steps">
|
||||
<h5>{{'APP.PAGES.NEXTSTEPS.TITLE' | translate}}</h5>
|
||||
<div class="row">
|
||||
<div class="step">
|
||||
<h6>{{ 'APP.PAGES.NEXTSTEPS.0.TITLE' | translate }}</h6>
|
||||
<p>{{'APP.PAGES.NEXTSTEPS.0.DESC' | translate}}</p>
|
||||
<span class="fill-space"></span>
|
||||
<a [routerLink]="['/projects', this.projectId]" color="primary" mat-mini-fab><i
|
||||
class="las la-angle-right"></i></a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</app-card>
|
||||
<div class="step">
|
||||
<h6>{{ 'APP.PAGES.NEXTSTEPS.1.TITLE' | translate }}</h6>
|
||||
<p>{{'APP.PAGES.NEXTSTEPS.1.DESC' | translate}}</p>
|
||||
<span class="fill-space"></span>
|
||||
<a [routerLink]="['/users', 'create']" color="primary" mat-mini-fab><i
|
||||
class="las la-angle-right"></i></a>
|
||||
</div>
|
||||
<div class="step">
|
||||
<h6>{{ 'APP.PAGES.NEXTSTEPS.2.TITLE' | translate }}</h6>
|
||||
<p>{{'APP.PAGES.NEXTSTEPS.2.DESC' | translate}}</p>
|
||||
<span class="fill-space"></span>
|
||||
<a href="https://docs.zitadel.ch" color="primary" mat-mini-fab><i
|
||||
class="las la-angle-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="side" metainfo>
|
||||
<div class="meta-details">
|
||||
<div class="meta-row">
|
||||
|
@ -8,11 +8,21 @@
|
||||
display: block;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.2rem;
|
||||
margin: 0 1rem;
|
||||
.title-col {
|
||||
margin-left: 2rem;
|
||||
font-weight: normal;
|
||||
margin-right: 1rem;
|
||||
min-width: 200px;
|
||||
|
||||
h1 {
|
||||
font-size: 1.2rem;
|
||||
margin: 0 0 0 0;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 12px;
|
||||
color: var(--grey);
|
||||
}
|
||||
}
|
||||
|
||||
.desc {
|
||||
@ -20,6 +30,7 @@
|
||||
display: block;
|
||||
font-size: .9rem;
|
||||
color: var(--grey);
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.zitadel-warning {
|
||||
@ -41,10 +52,10 @@
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
|
||||
.toggle {
|
||||
outline: none;
|
||||
align-self: flex-start;
|
||||
margin-top: 1rem;
|
||||
margin-right: 1rem;
|
||||
border-radius: .5rem;
|
||||
@ -91,6 +102,11 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.redirect-section {
|
||||
flex: 1;
|
||||
margin: 0 .5rem;
|
||||
}
|
||||
|
||||
.formfield {
|
||||
flex: 1 1 30%;
|
||||
margin: 0 .5rem;
|
||||
@ -99,27 +115,9 @@
|
||||
flex-basis: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.chiplist {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.chip-form {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.formfield {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.section-title {
|
||||
margin-bottom: 1.5rem;
|
||||
margin: 1.5rem 0 0 0;
|
||||
}
|
||||
|
||||
.full-width {
|
||||
@ -142,7 +140,7 @@
|
||||
.desc {
|
||||
color: var(--grey);
|
||||
font-size: 14px;
|
||||
margin-bottom: 1rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.devmode {
|
||||
@ -170,18 +168,67 @@
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.chip {
|
||||
border-radius: 4px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.chip[color='green'] {
|
||||
background-color: #56a392 !important;
|
||||
}
|
||||
|
||||
.divider {
|
||||
flex-basis: 100%;
|
||||
margin: 1.5rem .5rem;
|
||||
height: 1px;
|
||||
background-color: rgba(#8795a1, .2);
|
||||
}
|
||||
|
||||
.next-steps {
|
||||
h5 {
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
color: var(--grey);
|
||||
}
|
||||
|
||||
.row {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
overflow-x: auto;
|
||||
|
||||
.step {
|
||||
min-width: 220px;
|
||||
max-width: 280px;
|
||||
padding: 1rem;
|
||||
margin: 0 .5rem;
|
||||
border: 1px solid var(--grey);
|
||||
border-radius: .5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
flex: 1;
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
text-align: center;
|
||||
margin: 0 0 1rem 0;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
color: var(--grey);
|
||||
}
|
||||
|
||||
.fill-space {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
button {
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -4,12 +4,14 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
import { MatButtonToggleChange } from '@angular/material/button-toggle';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ActivatedRoute, Params } from '@angular/router';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Duration } from 'google-protobuf/google/protobuf/duration_pb';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { RadioItemAuthType } from 'src/app/modules/app-radio/app-auth-method-radio/app-auth-method-radio.component';
|
||||
import { ChangeType } from 'src/app/modules/changes/changes.component';
|
||||
import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
|
||||
import {
|
||||
Application,
|
||||
AppState,
|
||||
@ -27,11 +29,7 @@ import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
|
||||
import { AppSecretDialogComponent } from '../app-secret-dialog/app-secret-dialog.component';
|
||||
|
||||
enum RedirectType {
|
||||
REDIRECT = 'redirect',
|
||||
POSTREDIRECT = 'postredirect',
|
||||
}
|
||||
import { CODE_METHOD, getAuthMethodFromPartialConfig, getPartialConfigFromAuthMethod, IMPLICIT_METHOD, PKCE_METHOD, PK_JWT_METHOD, POST_METHOD, CUSTOM_METHOD } from '../authmethods';
|
||||
|
||||
@Component({
|
||||
selector: 'app-app-detail',
|
||||
@ -39,12 +37,20 @@ enum RedirectType {
|
||||
styleUrls: ['./app-detail.component.scss'],
|
||||
})
|
||||
export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
public editState: boolean = false;
|
||||
public currentAuthMethod: string = CUSTOM_METHOD.key;
|
||||
public initialAuthMethod: string = CUSTOM_METHOD.key;
|
||||
public canWrite: boolean = false;
|
||||
public errorMessage: string = '';
|
||||
public removable: boolean = true;
|
||||
public addOnBlur: boolean = true;
|
||||
public readonly separatorKeysCodes: number[] = [ENTER, COMMA, SPACE];
|
||||
|
||||
public authMethods: RadioItemAuthType[] = [
|
||||
PKCE_METHOD,
|
||||
CODE_METHOD,
|
||||
POST_METHOD,
|
||||
];
|
||||
private subscription?: Subscription;
|
||||
public projectId: string = '';
|
||||
public app!: Application.AsObject;
|
||||
@ -78,11 +84,10 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
public AppState: any = AppState;
|
||||
public appNameForm!: FormGroup;
|
||||
public appForm!: FormGroup;
|
||||
|
||||
public redirectUrisList: string[] = [];
|
||||
public postLogoutRedirectUrisList: string[] = [];
|
||||
|
||||
public RedirectType: any = RedirectType;
|
||||
|
||||
public isZitadel: boolean = false;
|
||||
public docs!: ZitadelDocs.AsObject;
|
||||
|
||||
@ -90,9 +95,6 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
public OIDCAuthMethodType: any = OIDCAuthMethodType;
|
||||
public OIDCTokenType: any = OIDCTokenType;
|
||||
|
||||
public redirectControl: FormControl = new FormControl({ value: '', disabled: true });
|
||||
public postRedirectControl: FormControl = new FormControl({ value: '', disabled: true });
|
||||
|
||||
public ChangeType: any = ChangeType;
|
||||
constructor(
|
||||
public translate: TranslateService,
|
||||
@ -103,6 +105,7 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
private dialog: MatDialog,
|
||||
private mgmtService: ManagementService,
|
||||
private authService: GrpcAuthService,
|
||||
private router: Router,
|
||||
) {
|
||||
this.appNameForm = this.fb.group({
|
||||
state: [{ value: '', disabled: true }, []],
|
||||
@ -145,12 +148,23 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
this.mgmtService.GetApplicationById(projectid, id).then(app => {
|
||||
this.app = app.toObject();
|
||||
this.appNameForm.patchValue(this.app);
|
||||
console.log(this.app);
|
||||
|
||||
this.getAuthMethodOptions();
|
||||
if (this.app.oidcConfig) {
|
||||
this.initialAuthMethod = this.authMethodFromPartialConfig(this.app.oidcConfig);
|
||||
this.currentAuthMethod = this.initialAuthMethod;
|
||||
if (this.initialAuthMethod === CUSTOM_METHOD.key) {
|
||||
if (!this.authMethods.includes(CUSTOM_METHOD)) {
|
||||
this.authMethods.push(CUSTOM_METHOD);
|
||||
}
|
||||
} else {
|
||||
this.authMethods = this.authMethods.filter(element => element != CUSTOM_METHOD);
|
||||
}
|
||||
}
|
||||
|
||||
if (allowed) {
|
||||
this.appNameForm.enable();
|
||||
this.appForm.enable();
|
||||
this.redirectControl.enable();
|
||||
this.postRedirectControl.enable();
|
||||
}
|
||||
|
||||
if (this.app.oidcConfig?.redirectUrisList) {
|
||||
@ -161,12 +175,22 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
if (this.app.oidcConfig?.clockSkew) {
|
||||
const inSecs = this.app.oidcConfig?.clockSkew.seconds + this.app.oidcConfig?.clockSkew.nanos / 100000;
|
||||
console.log(inSecs);
|
||||
this.appForm.controls['clockSkewSeconds'].setValue(inSecs);
|
||||
}
|
||||
if (this.app.oidcConfig) {
|
||||
this.appForm.patchValue(this.app.oidcConfig);
|
||||
}
|
||||
|
||||
this.appForm.valueChanges.subscribe(oidcConfig => {
|
||||
this.initialAuthMethod = this.authMethodFromPartialConfig(oidcConfig);
|
||||
if (this.initialAuthMethod === CUSTOM_METHOD.key) {
|
||||
if (!this.authMethods.includes(CUSTOM_METHOD)) {
|
||||
this.authMethods.push(CUSTOM_METHOD);
|
||||
}
|
||||
} else {
|
||||
this.authMethods = this.authMethods.filter(element => element != CUSTOM_METHOD);
|
||||
}
|
||||
});
|
||||
}).catch(error => {
|
||||
console.error(error);
|
||||
this.toast.showError(error);
|
||||
@ -176,6 +200,69 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
this.docs = (await this.mgmtService.GetZitadelDocs()).toObject();
|
||||
}
|
||||
|
||||
private getAuthMethodOptions(): void {
|
||||
switch (this.app.oidcConfig?.applicationType) {
|
||||
case OIDCApplicationType.OIDCAPPLICATIONTYPE_NATIVE:
|
||||
this.authMethods = [
|
||||
PKCE_METHOD,
|
||||
CUSTOM_METHOD,
|
||||
];
|
||||
break;
|
||||
case OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB:
|
||||
this.authMethods = [
|
||||
PKCE_METHOD,
|
||||
CODE_METHOD,
|
||||
POST_METHOD,
|
||||
];
|
||||
break;
|
||||
case OIDCApplicationType.OIDCAPPLICATIONTYPE_USER_AGENT:
|
||||
this.authMethods = [
|
||||
PKCE_METHOD,
|
||||
IMPLICIT_METHOD,
|
||||
];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public authMethodFromPartialConfig(config: OIDCConfig.AsObject): string {
|
||||
const key = getAuthMethodFromPartialConfig(config);
|
||||
return key;
|
||||
}
|
||||
|
||||
public setPartialConfigFromAuthMethod(authMethod: string): void {
|
||||
const partialConfig = getPartialConfigFromAuthMethod(authMethod);
|
||||
|
||||
if (partialConfig && this.app.oidcConfig) {
|
||||
this.app.oidcConfig.responseTypesList = partialConfig.responseTypesList ?? [];
|
||||
this.app.oidcConfig.grantTypesList = partialConfig.grantTypesList ?? [];
|
||||
this.app.oidcConfig.authMethodType = partialConfig.authMethodType ?? OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE;
|
||||
this.appForm.patchValue(this.app.oidcConfig);
|
||||
}
|
||||
}
|
||||
|
||||
public deleteApp(): void {
|
||||
const dialogRef = this.dialog.open(WarnDialogComponent, {
|
||||
data: {
|
||||
confirmKey: 'ACTIONS.DELETE',
|
||||
cancelKey: 'ACTIONS.CANCEL',
|
||||
titleKey: 'APP.PAGES.DIALOG.DELETE.TITLE',
|
||||
descriptionKey: 'APP.PAGES.DIALOG.DELETE.DESCRIPTION',
|
||||
},
|
||||
width: '400px',
|
||||
});
|
||||
dialogRef.afterClosed().subscribe(resp => {
|
||||
if (resp && this.projectId && this.app.id) {
|
||||
this.mgmtService.RemoveApplication(this.projectId, this.app.id).then(() => {
|
||||
this.toast.showInfo('APP.TOAST.DELETED', true);
|
||||
|
||||
this.router.navigate(['/projects', this.projectId]);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public changeState(event: MatButtonToggleChange): void {
|
||||
if (event.value === AppState.APPSTATE_ACTIVE) {
|
||||
this.mgmtService.ReactivateApplication(this.projectId, this.app.id).then(() => {
|
||||
@ -192,40 +279,6 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
public add(input: any, target: RedirectType): void {
|
||||
if (target === RedirectType.POSTREDIRECT && this.postRedirectControl.valid) {
|
||||
if (input.value !== '' && input.value !== ' ' && input.value !== '/') {
|
||||
this.postLogoutRedirectUrisList.push(input.value);
|
||||
}
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
} else if (target === RedirectType.REDIRECT && this.redirectControl.valid) {
|
||||
if (input.value !== '' && input.value !== ' ' && input.value !== '/') {
|
||||
this.redirectUrisList.push(input.value);
|
||||
}
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public remove(redirect: any, target: RedirectType): void {
|
||||
if (target === RedirectType.POSTREDIRECT) {
|
||||
const index = this.postLogoutRedirectUrisList.indexOf(redirect);
|
||||
|
||||
if (index >= 0) {
|
||||
this.postLogoutRedirectUrisList.splice(index, 1);
|
||||
}
|
||||
} else if (target === RedirectType.REDIRECT) {
|
||||
const index = this.redirectUrisList.indexOf(redirect);
|
||||
|
||||
if (index >= 0) {
|
||||
this.redirectUrisList.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public saveApp(): void {
|
||||
if (this.appNameForm.valid) {
|
||||
this.app.name = this.name?.value;
|
||||
@ -234,6 +287,7 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
.UpdateApplication(this.projectId, this.app.id, this.name?.value)
|
||||
.then(() => {
|
||||
this.toast.showInfo('APP.TOAST.OIDCUPDATED', true);
|
||||
this.editState = false;
|
||||
})
|
||||
.catch(error => {
|
||||
this.toast.showError(error);
|
||||
@ -282,10 +336,12 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
dur.setNanos((Math.floor(this.clockSkewSeconds?.value % 1) * 10000));
|
||||
req.setClockSkew(dur);
|
||||
}
|
||||
console.log(req.toObject());
|
||||
this.mgmtService
|
||||
.UpdateOIDCAppConfig(req)
|
||||
.then(() => {
|
||||
if (this.app.oidcConfig) {
|
||||
this.currentAuthMethod = this.authMethodFromPartialConfig(this.app.oidcConfig);
|
||||
}
|
||||
this.toast.showInfo('APP.TOAST.OIDCUPDATED', true);
|
||||
})
|
||||
.catch(error => {
|
||||
|
@ -19,6 +19,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { CopyToClipboardModule } from 'src/app/directives/copy-to-clipboard/copy-to-clipboard.module';
|
||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
import { AppRadioModule } from 'src/app/modules/app-radio/app-radio.module';
|
||||
import { CardModule } from 'src/app/modules/card/card.module';
|
||||
import { ChangesModule } from 'src/app/modules/changes/changes.module';
|
||||
import { InfoSectionModule } from 'src/app/modules/info-section/info-section.module';
|
||||
@ -29,15 +30,20 @@ import { AppCreateComponent } from './app-create/app-create.component';
|
||||
import { AppDetailComponent } from './app-detail/app-detail.component';
|
||||
import { AppSecretDialogComponent } from './app-secret-dialog/app-secret-dialog.component';
|
||||
import { AppsRoutingModule } from './apps-routing.module';
|
||||
import { A11yModule } from '@angular/cdk/a11y';
|
||||
import { RedirectUrisComponent } from './redirect-uris/redirect-uris.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppCreateComponent,
|
||||
AppDetailComponent,
|
||||
AppSecretDialogComponent,
|
||||
RedirectUrisComponent,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
A11yModule,
|
||||
AppRadioModule,
|
||||
AppsRoutingModule,
|
||||
FormsModule,
|
||||
TranslateModule,
|
||||
|
166
console/src/app/pages/projects/apps/authmethods.ts
Normal file
166
console/src/app/pages/projects/apps/authmethods.ts
Normal file
@ -0,0 +1,166 @@
|
||||
import { RadioItemAuthType } from 'src/app/modules/app-radio/app-auth-method-radio/app-auth-method-radio.component';
|
||||
import { OIDCAuthMethodType, OIDCConfig, OIDCGrantType, OIDCResponseType } from 'src/app/proto/generated/management_pb';
|
||||
|
||||
export const CODE_METHOD: RadioItemAuthType = {
|
||||
key: 'CODE',
|
||||
titleI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.CODE.TITLE',
|
||||
descI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.CODE.DESCRIPTION',
|
||||
disabled: false,
|
||||
prefix: 'CODE',
|
||||
background: 'rgb(89 115 128)',
|
||||
responseType: OIDCResponseType.OIDCRESPONSETYPE_CODE,
|
||||
grantType: OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE,
|
||||
authMethod: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_BASIC,
|
||||
recommended: false,
|
||||
};
|
||||
export const PKCE_METHOD: RadioItemAuthType = {
|
||||
key: 'PKCE',
|
||||
titleI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.PKCE.TITLE',
|
||||
descI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.PKCE.DESCRIPTION',
|
||||
disabled: false,
|
||||
prefix: 'PKCE',
|
||||
background: 'rgb(80 110 92)',
|
||||
responseType: OIDCResponseType.OIDCRESPONSETYPE_CODE,
|
||||
grantType: OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE,
|
||||
authMethod: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE,
|
||||
recommended: true,
|
||||
};
|
||||
export const POST_METHOD: RadioItemAuthType = {
|
||||
key: 'POST',
|
||||
titleI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.POST.TITLE',
|
||||
descI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.POST.DESCRIPTION',
|
||||
disabled: false,
|
||||
prefix: 'POST',
|
||||
background: '#595d80',
|
||||
responseType: OIDCResponseType.OIDCRESPONSETYPE_CODE,
|
||||
grantType: OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE,
|
||||
authMethod: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_POST,
|
||||
notRecommended: true,
|
||||
};
|
||||
export const PK_JWT_METHOD: RadioItemAuthType = {
|
||||
key: 'PK_JWT',
|
||||
titleI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.ALTERNATIVE.TITLE',
|
||||
descI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.ALTERNATIVE.DESCRIPTION',
|
||||
disabled: false,
|
||||
prefix: 'PK_JWT',
|
||||
background: '#6a506e',
|
||||
responseType: OIDCResponseType.OIDCRESPONSETYPE_CODE,
|
||||
grantType: OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE,
|
||||
authMethod: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_POST,
|
||||
};
|
||||
export const IMPLICIT_METHOD: RadioItemAuthType = {
|
||||
key: 'IMPLICIT',
|
||||
titleI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.IMPLICIT.TITLE',
|
||||
descI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.IMPLICIT.DESCRIPTION',
|
||||
disabled: false,
|
||||
prefix: 'IMP',
|
||||
background: 'rgb(144 75 75)',
|
||||
responseType: OIDCResponseType.OIDCRESPONSETYPE_ID_TOKEN,
|
||||
grantType: OIDCGrantType.OIDCGRANTTYPE_IMPLICIT,
|
||||
authMethod: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE,
|
||||
notRecommended: true,
|
||||
};
|
||||
export const CUSTOM_METHOD: RadioItemAuthType = {
|
||||
key: 'CUSTOM',
|
||||
titleI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.CUSTOM.TITLE',
|
||||
descI18nKey: 'APP.OIDC.SELECTION.AUTHMETHOD.CUSTOM.DESCRIPTION',
|
||||
disabled: false,
|
||||
prefix: 'CUSTOM',
|
||||
background: '#333',
|
||||
};
|
||||
|
||||
export function getPartialConfigFromAuthMethod(authMethod: string): Partial<OIDCConfig.AsObject> | undefined {
|
||||
let config: Partial<OIDCConfig.AsObject>;
|
||||
switch (authMethod) {
|
||||
case CODE_METHOD.key:
|
||||
config = {
|
||||
responseTypesList: [OIDCResponseType.OIDCRESPONSETYPE_CODE],
|
||||
grantTypesList: [OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE],
|
||||
authMethodType: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_BASIC,
|
||||
};
|
||||
return config;
|
||||
case PKCE_METHOD.key:
|
||||
config = {
|
||||
responseTypesList: [OIDCResponseType.OIDCRESPONSETYPE_CODE],
|
||||
grantTypesList: [OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE],
|
||||
authMethodType: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE,
|
||||
};
|
||||
return config;
|
||||
case POST_METHOD.key:
|
||||
config = {
|
||||
responseTypesList: [OIDCResponseType.OIDCRESPONSETYPE_CODE],
|
||||
grantTypesList: [OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE],
|
||||
authMethodType: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_POST,
|
||||
};
|
||||
return config;
|
||||
// case PK_JWT_METHOD.key:
|
||||
// config = {
|
||||
// responseTypesList: [OIDCResponseType.OIDCRESPONSETYPE_CODE],
|
||||
// grantTypesList: [OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE],
|
||||
// authMethodType: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE,
|
||||
// };
|
||||
// return config;
|
||||
case IMPLICIT_METHOD.key:
|
||||
config = {
|
||||
responseTypesList: [OIDCResponseType.OIDCRESPONSETYPE_ID_TOKEN_TOKEN],
|
||||
grantTypesList: [OIDCGrantType.OIDCGRANTTYPE_IMPLICIT],
|
||||
authMethodType: OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE,
|
||||
};
|
||||
return config;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function getAuthMethodFromPartialConfig(config: Partial<OIDCConfig.AsObject> | OIDCConfig.AsObject): string {
|
||||
const toCheck = [config.responseTypesList, config.grantTypesList, config.authMethodType];
|
||||
const code = JSON.stringify(
|
||||
[
|
||||
[OIDCResponseType.OIDCRESPONSETYPE_CODE],
|
||||
[OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE],
|
||||
OIDCAuthMethodType.OIDCAUTHMETHODTYPE_BASIC,
|
||||
]
|
||||
);
|
||||
|
||||
const pkce = JSON.stringify(
|
||||
[
|
||||
[OIDCResponseType.OIDCRESPONSETYPE_CODE],
|
||||
[OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE],
|
||||
OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE,
|
||||
]
|
||||
);
|
||||
|
||||
const post = JSON.stringify(
|
||||
[
|
||||
[OIDCResponseType.OIDCRESPONSETYPE_CODE],
|
||||
[OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE],
|
||||
OIDCAuthMethodType.OIDCAUTHMETHODTYPE_POST,
|
||||
]
|
||||
);
|
||||
|
||||
// const pk_jwt = JSON.stringify(
|
||||
// [
|
||||
// [OIDCResponseType.OIDCRESPONSETYPE_CODE],
|
||||
// [OIDCGrantType.OIDCGRANTTYPE_AUTHORIZATION_CODE],
|
||||
// OIDCAuthMethodType.OIDCAUTHMETHODTYPE_BASIC,
|
||||
// ]
|
||||
// );
|
||||
|
||||
const implicit = JSON.stringify(
|
||||
[
|
||||
[OIDCResponseType.OIDCRESPONSETYPE_ID_TOKEN_TOKEN],
|
||||
[OIDCGrantType.OIDCGRANTTYPE_IMPLICIT],
|
||||
OIDCAuthMethodType.OIDCAUTHMETHODTYPE_NONE,
|
||||
]
|
||||
);
|
||||
|
||||
switch (JSON.stringify(toCheck)) {
|
||||
case code: return CODE_METHOD.key;
|
||||
case pkce: return PKCE_METHOD.key;
|
||||
case post: return POST_METHOD.key;
|
||||
// case pk_jwt: return PK_JWT_METHOD.key;
|
||||
case implicit: return IMPLICIT_METHOD.key;
|
||||
default:
|
||||
return CUSTOM_METHOD.key;
|
||||
}
|
||||
}
|
25
console/src/app/pages/projects/apps/authtypes.ts
Normal file
25
console/src/app/pages/projects/apps/authtypes.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { OIDCApplicationType } from 'src/app/proto/generated/management_pb';
|
||||
|
||||
export const WEB_TYPE = {
|
||||
titleI18nKey: 'APP.OIDC.SELECTION.APPTYPE.WEB.TITLE',
|
||||
descI18nKey: 'APP.OIDC.SELECTION.APPTYPE.WEB.DESCRIPTION',
|
||||
type: OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB,
|
||||
prefix: 'WEB',
|
||||
background: 'rgb(80, 110, 110)',
|
||||
};
|
||||
|
||||
export const USER_AGENT_TYPE = {
|
||||
titleI18nKey: 'APP.OIDC.SELECTION.APPTYPE.USERAGENT.TITLE',
|
||||
descI18nKey: 'APP.OIDC.SELECTION.APPTYPE.USERAGENT.DESCRIPTION',
|
||||
type: OIDCApplicationType.OIDCAPPLICATIONTYPE_USER_AGENT,
|
||||
prefix: 'UA',
|
||||
background: '#6a506e',
|
||||
};
|
||||
|
||||
export const NATIVE_TYPE = {
|
||||
titleI18nKey: 'APP.OIDC.SELECTION.APPTYPE.NATIVE.TITLE',
|
||||
descI18nKey: 'APP.OIDC.SELECTION.APPTYPE.NATIVE.DESCRIPTION',
|
||||
type: OIDCApplicationType.OIDCAPPLICATIONTYPE_NATIVE,
|
||||
prefix: 'N',
|
||||
background: '#595d80',
|
||||
};
|
@ -0,0 +1,28 @@
|
||||
<form class="form" (ngSubmit)="add(redInput)">
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ title }}</cnsl-label>
|
||||
|
||||
<input #redInput cnslInput placeholder="ex. https://" [formControl]="redirectControl">
|
||||
</cnsl-form-field>
|
||||
<button matTooltip="{{'ACTIONS.ADD' | translate}}" type="submit" mat-icon-button
|
||||
[disabled]="redirectControl.invalid || !canWrite">
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="uri-list">
|
||||
<div *ngFor="let uri of urisList" class="uri-line">
|
||||
<span class="uri"
|
||||
[ngClass]="{'green': !devMode && uri?.startsWith('https://'), 'red': !devMode && !uri?.startsWith('https://')}">{{uri}}</span>
|
||||
<span class="fill-space"></span>
|
||||
<i *ngIf="!devMode && !uri?.startsWith('https://')" class="las la-exclamation red"></i>
|
||||
<!-- <i *ngIf="!devMode && uri?.startsWith('https://')" class="las la-check green"></i> -->
|
||||
|
||||
<button matTooltip="{{'ACTIONS.DELETE' | translate}}" mat-icon-button (click)="remove(uri)" class="icon-button">
|
||||
<mat-icon>cancel</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p *ngIf="redirectControl.value && redirectControl.invalid" class="error">
|
||||
{{'APP.OIDC.REDIRECTNOTVALID' | translate}}</p>
|
@ -0,0 +1,61 @@
|
||||
.form {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
min-width: 320px;
|
||||
|
||||
.formfield {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-bottom: 14px;
|
||||
margin-right: -0.5rem;
|
||||
}
|
||||
}
|
||||
.uri-list {
|
||||
margin: 0 .5rem;
|
||||
width: 100%;
|
||||
|
||||
.uri-line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.uri {
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.fill-space {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
i.green {
|
||||
font-size: 1rem;
|
||||
line-height: 35px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
i.red {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
|
||||
mat-icon {
|
||||
font-size: 1rem !important;
|
||||
}
|
||||
|
||||
&:not(:hover) {
|
||||
color: var(--grey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.error {
|
||||
font-size: 13px;
|
||||
color: #f44336;
|
||||
margin: 0 .5rem 1.5rem .5rem;
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { RedirectUrisComponent } from './redirect-uris.component';
|
||||
|
||||
describe('RedirectUrisComponent', () => {
|
||||
let component: RedirectUrisComponent;
|
||||
let fixture: ComponentFixture<RedirectUrisComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ RedirectUrisComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(RedirectUrisComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,43 @@
|
||||
import { Component, EventEmitter, Input, OnInit } from '@angular/core';
|
||||
import { FormControl } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-redirect-uris',
|
||||
templateUrl: './redirect-uris.component.html',
|
||||
styleUrls: ['./redirect-uris.component.scss']
|
||||
})
|
||||
export class RedirectUrisComponent implements OnInit {
|
||||
@Input() title: string = '';
|
||||
@Input() devMode: boolean = false;
|
||||
@Input() canWrite: boolean = false;
|
||||
@Input() public urisList: string[] = [];
|
||||
@Input() public redirectControl: FormControl = new FormControl({ value: '', disabled: true });
|
||||
@Input() public changedUris: EventEmitter<string[]> = new EventEmitter();
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
if (this.canWrite) {
|
||||
this.redirectControl.enable();
|
||||
}
|
||||
}
|
||||
|
||||
public add(input: any): void {
|
||||
if (this.redirectControl.valid) {
|
||||
if (input.value !== '' && input.value !== ' ' && input.value !== '/') {
|
||||
this.urisList.push(input.value);
|
||||
}
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public remove(redirect: any): void {
|
||||
console.log(redirect);
|
||||
const index = this.urisList.indexOf(redirect);
|
||||
|
||||
if (index >= 0) {
|
||||
this.urisList.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
@ -11,18 +11,27 @@
|
||||
</div>
|
||||
|
||||
<div [routerLink]="['/projects', projectId, 'apps', app.id ]" class="app-wrap"
|
||||
*ngFor="let app of appsSubject | async">
|
||||
<div class="morph-card" matRipple>
|
||||
*ngFor="let app of appsSubject | async"
|
||||
matTooltip="{{'APP.OIDC.APPTYPE'+app.oidcConfig.applicationType | translate}}">
|
||||
<cnsl-app-card class="grid-card" matRipple [type]="app.oidcConfig?.applicationType">
|
||||
{{ app.name.charAt(0)}}
|
||||
</div>
|
||||
<i *ngIf="app.oidcConfig.applicationType == OIDCApplicationType.OIDCAPPLICATIONTYPE_NATIVE"
|
||||
class="las la-mobile"></i>
|
||||
<i *ngIf="app.oidcConfig.applicationType == OIDCApplicationType.OIDCAPPLICATIONTYPE_WEB"
|
||||
class="las la-code"></i>
|
||||
<i *ngIf="app.oidcConfig.applicationType == OIDCApplicationType.OIDCAPPLICATIONTYPE_USER_AGENT"
|
||||
class="las la-code"></i>
|
||||
</cnsl-app-card>
|
||||
<span class="name">{{app.name}}</span>
|
||||
<span class="type">{{'APP.OIDC.APPTYPE'+app.oidcConfig.applicationType | translate}}</span>
|
||||
|
||||
</div>
|
||||
|
||||
<ng-template appHasRole [appHasRole]="['project.app.write']">
|
||||
<div class="app-wrap" *ngIf="!disabled" [routerLink]="[ '/projects', projectId, 'apps', 'create']">
|
||||
<div class="morph-card add" matRipple>
|
||||
<cnsl-app-card class="grid-card add" matRipple>
|
||||
<mat-icon>add</mat-icon>
|
||||
</div>
|
||||
</cnsl-app-card>
|
||||
<span class="name">{{ 'ACTIONS.NEW' | translate }}</span>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
@ -1,82 +1,62 @@
|
||||
@import '~@angular/material/theming';
|
||||
|
||||
@mixin application-grid-theme($theme) {
|
||||
/* stylelint-disable */
|
||||
$primary: map-get($theme, primary);
|
||||
$primary-dark: mat-color($primary, A900);
|
||||
$accent: map-get($theme, accent);
|
||||
$accent-color: mat-color($primary, 500);
|
||||
/* stylelint-enable */
|
||||
|
||||
.app-grid-header {
|
||||
.app-grid-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.fill-space {
|
||||
flex: 1;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.app-container {
|
||||
.app-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -1rem;
|
||||
padding-bottom: 2rem;
|
||||
|
||||
.sp-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: calc(82px + 2rem);
|
||||
height: calc(82px + 2rem);
|
||||
}
|
||||
|
||||
.app-wrap {
|
||||
outline: none;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
max-width: 150px;
|
||||
|
||||
.morph-card {
|
||||
cursor: pointer;
|
||||
animation: all .2s;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 2rem;
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
margin: 1rem;
|
||||
text-transform: uppercase;
|
||||
border-radius: .5rem;
|
||||
border: 2px solid $accent-color;
|
||||
font-weight: 800;
|
||||
background-color: $primary-dark;
|
||||
transition: background-color box-shadow .3s ease-in;
|
||||
background-image:
|
||||
linear-gradient(transparent 11px, rgba($accent-color, .5) 12px, transparent 12px),
|
||||
linear-gradient(90deg, transparent 11px, rgba($accent-color, .5) 12px, transparent 12px);
|
||||
background-size: 100% 12px, 12px 100%;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba($accent-color, .1);
|
||||
}
|
||||
|
||||
&.add {
|
||||
background: $accent-color;
|
||||
color: white;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba($accent-color, .8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: .8rem;
|
||||
color: #8a868a;
|
||||
}
|
||||
width: calc(82px + 2rem);
|
||||
height: calc(82px + 2rem);
|
||||
}
|
||||
|
||||
.app-wrap {
|
||||
outline: none;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
max-width: 150px;
|
||||
|
||||
.grid-card {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 2rem;
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
margin: 1rem;
|
||||
text-transform: uppercase;
|
||||
border-radius: .5rem;
|
||||
font-weight: 800;
|
||||
box-sizing: border-box;
|
||||
|
||||
&.add {
|
||||
border: 2px solid var(--grey);
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.type {
|
||||
font-size: 12px;
|
||||
color: #8a868a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { BehaviorSubject, from, Observable, of } from 'rxjs';
|
||||
import { catchError, finalize, map } from 'rxjs/operators';
|
||||
import { Application } from 'src/app/proto/generated/management_pb';
|
||||
import { Application, OIDCApplicationType, OIDCResponseType } from 'src/app/proto/generated/management_pb';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { NATIVE_TYPE, USER_AGENT_TYPE, WEB_TYPE } from '../../../apps/authtypes';
|
||||
|
||||
@Component({
|
||||
selector: 'app-application-grid',
|
||||
@ -16,6 +17,11 @@ export class ApplicationGridComponent implements OnInit {
|
||||
public appsSubject: BehaviorSubject<Application.AsObject[]> = new BehaviorSubject<Application.AsObject[]>([]);
|
||||
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
|
||||
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
|
||||
public OIDCApplicationType: any = OIDCApplicationType;
|
||||
|
||||
public NATIVE_TYPE: any = NATIVE_TYPE;
|
||||
public WEB_TYPE: any = WEB_TYPE;
|
||||
public USER_AGENT_TYPE: any = USER_AGENT_TYPE;
|
||||
|
||||
constructor(private mgmtService: ManagementService) { }
|
||||
|
||||
|
@ -24,10 +24,17 @@
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.ROLE.NAME' | translate }} </th>
|
||||
<td class="pointer" [routerLink]="['/projects', projectId, 'apps', role.id ]" mat-cell
|
||||
*matCellDef="let role">
|
||||
{{role.name}} </td>
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'APP.NAME' | translate }} </th>
|
||||
<td class="pointer" [routerLink]="['/projects', projectId, 'apps', app.id ]" mat-cell
|
||||
*matCellDef="let app">
|
||||
{{app.name}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'APP.OIDC.APPTYPE' | translate }} </th>
|
||||
<td class="pointer" [routerLink]="['/projects', projectId, 'apps', app.id ]" mat-cell
|
||||
*matCellDef="let app">
|
||||
{{'APP.OIDC.APPTYPE'+app?.oidcConfig?.applicationType | translate}} </td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
|
@ -26,7 +26,7 @@ export class ApplicationsComponent implements AfterViewInit, OnInit {
|
||||
public dataSource!: ProjectApplicationsDataSource;
|
||||
public selection: SelectionModel<Application.AsObject> = new SelectionModel<Application.AsObject>(true, []);
|
||||
|
||||
public displayedColumns: string[] = ['select', 'name'];
|
||||
public displayedColumns: string[] = ['select', 'name', 'type'];
|
||||
|
||||
constructor(private mgmtService: ManagementService, private toast: ToastService) { }
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
<ng-template appHasRole [appHasRole]="['project.write:'+projectId, 'project.write']">
|
||||
<button matTooltip="{{'ACTIONS.EDIT' | translate}}" mat-icon-button (click)="editstate = !editstate"
|
||||
aria-label="Edit project name" *ngIf="isZitadel === false">
|
||||
<mat-icon *ngIf="!editstate">edit</mat-icon>
|
||||
<i *ngIf="!editstate" class="las la-edit"></i>
|
||||
<mat-icon *ngIf="editstate">close</mat-icon>
|
||||
</button>
|
||||
</ng-template>
|
||||
@ -24,11 +24,13 @@
|
||||
<button mat-stroked-button color="warn"
|
||||
[disabled]="isZitadel || (['project.write$', 'project.write:'+ project.projectId]| hasRole | async) == false"
|
||||
*ngIf="project?.state === ProjectState.PROJECTSTATE_ACTIVE"
|
||||
(click)="changeState(ProjectState.PROJECTSTATE_INACTIVE)">{{'PROJECT.TABLE.DEACTIVATE' | translate}}</button>
|
||||
(click)="changeState(ProjectState.PROJECTSTATE_INACTIVE)">{{'PROJECT.TABLE.DEACTIVATE' |
|
||||
translate}}</button>
|
||||
<button mat-stroked-button color="warn"
|
||||
[disabled]="isZitadel || (['project.write$', 'project.write:'+ project.projectId]| hasRole | async) == false"
|
||||
*ngIf="project?.state === ProjectState.PROJECTSTATE_INACTIVE"
|
||||
(click)="changeState(ProjectState.PROJECTSTATE_ACTIVE)">{{'PROJECT.TABLE.ACTIVATE' | translate}}</button>
|
||||
(click)="changeState(ProjectState.PROJECTSTATE_ACTIVE)">{{'PROJECT.TABLE.ACTIVATE' |
|
||||
translate}}</button>
|
||||
|
||||
<div class="full-width">
|
||||
<div class="line">
|
||||
@ -78,7 +80,7 @@
|
||||
</ng-template>
|
||||
|
||||
<ng-template appHasRole [appHasRole]="['project.role.read:' + project.projectId, 'project.role.read']">
|
||||
<app-card title="{{ 'PROJECT.ROLE.TITLE' | translate }}"
|
||||
<app-card id="roles" title="{{ 'PROJECT.ROLE.TITLE' | translate }}"
|
||||
description="{{ 'PROJECT.ROLE.DESCRIPTION' | translate }}">
|
||||
<p>{{'PROJECT.ROLE.OPTIONS' | translate}}</p>
|
||||
<mat-checkbox [(ngModel)]="project.projectRoleAssertion" (change)="saveProject()"
|
||||
@ -118,7 +120,8 @@
|
||||
<div class="meta-row">
|
||||
<span class="first">{{'PROJECT.STATE.TITLE' | translate}}:</span>
|
||||
<span *ngIf="project && project.state !== undefined" class="state"
|
||||
[ngClass]="{'active': project.state === ProjectState.PROJECTSTATE_ACTIVE, 'inactive': project.state === ProjectState.PROJECTSTATE_INACTIVE}">{{'PROJECT.STATE.'+project.state | translate}}</span>
|
||||
[ngClass]="{'active': project.state === ProjectState.PROJECTSTATE_ACTIVE, 'inactive': project.state === ProjectState.PROJECTSTATE_INACTIVE}">{{'PROJECT.STATE.'+project.state
|
||||
| translate}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -14,6 +14,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
import { MemberCreateDialogModule } from 'src/app/modules/add-member-dialog/member-create-dialog.module';
|
||||
import { AppCardModule } from 'src/app/modules/app-card/app-card.module';
|
||||
import { CardModule } from 'src/app/modules/card/card.module';
|
||||
import { ChangesModule } from 'src/app/modules/changes/changes.module';
|
||||
import { ContributorsModule } from 'src/app/modules/contributors/contributors.module';
|
||||
@ -43,6 +44,7 @@ import { ProjectGrantsComponent } from './project-grants/project-grants.componen
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
AppCardModule,
|
||||
OwnedProjectDetailRoutingModule,
|
||||
TranslateModule,
|
||||
ReactiveFormsModule,
|
||||
|
@ -39,7 +39,7 @@
|
||||
<h1 class="h1">{{ 'PROJECT.GRANT.DETAIL.MEMBERTITLE' | translate }}</h1>
|
||||
<p class="desc">{{ 'PROJECT.GRANT.DETAIL.MEMBERDESC' | translate }}</p>
|
||||
|
||||
<app-members-table *ngIf="grant" style="width: 100%;" [dataSource]="dataSource"
|
||||
<app-members-table *ngIf="grant" style="width: 100%;" [dataSource]="dataSource" [canWrite]="['project.grant.member.write','project.grant.member.write:' + grant.id] | hasRole | async"
|
||||
[memberRoleOptions]="memberRoleOptions" (updateRoles)="updateMemberRoles($event.member, $event.change)"
|
||||
[factoryLoadFunc]="changePageFactory" (changedSelection)="selection = $event" [refreshTrigger]="changePage">
|
||||
<button selectactions (click)="removeProjectMemberSelection()"
|
||||
|
@ -7,8 +7,9 @@
|
||||
</ng-template>
|
||||
<p>{{'USER.SIGNEDOUT' | translate}}</p>
|
||||
|
||||
<button color="primary" mat-raised-button
|
||||
[routerLink]="[ '/users/me' ]">{{'USER.SIGNEDOUT_BTN' | translate}}</button>
|
||||
<button matTooltip="{{'ACTIONS.LOGIN' | translate}}" color="primary" mat-raised-button
|
||||
[routerLink]="[ '/users/me' ]">{{'USER.SIGNEDOUT_BTN' |
|
||||
translate}} <i class="las la-sign-in-alt"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -17,19 +17,24 @@
|
||||
p {
|
||||
color: var(--grey);
|
||||
text-align: center;
|
||||
font-size: 1rem;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 100px;
|
||||
max-width: 170px;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
button {
|
||||
display: block;
|
||||
padding: .5rem 4rem;
|
||||
|
||||
i {
|
||||
margin-left: .5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<ng-template appHasRole [appHasRole]="['user.membership.read']">
|
||||
<app-memberships [user]="user"></app-memberships>
|
||||
<app-memberships [auth]="true" [user]="user"></app-memberships>
|
||||
</ng-template>
|
||||
|
||||
<app-changes class="changes" [refresh]="refreshChanges$" [changeType]="ChangeType.MYUSER" [id]="user.id">
|
||||
|
@ -3,8 +3,10 @@ import { Component, Input, OnInit } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { Router } from '@angular/router';
|
||||
import { CreationType, MemberCreateDialogComponent } from 'src/app/modules/add-member-dialog/member-create-dialog.component';
|
||||
import { AuthServiceClient } from 'src/app/proto/generated/auth_grpc_web_pb';
|
||||
import { MemberType, UserMembershipSearchResponse, UserView } from 'src/app/proto/generated/management_pb';
|
||||
import { AdminService } from 'src/app/services/admin.service';
|
||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
|
||||
@ -33,12 +35,14 @@ export class MembershipsComponent implements OnInit {
|
||||
public loading: boolean = false;
|
||||
public memberships!: UserMembershipSearchResponse.AsObject;
|
||||
|
||||
@Input() public auth: boolean = false;
|
||||
@Input() public user!: UserView.AsObject;
|
||||
@Input() public disabled: boolean = false;
|
||||
|
||||
public MemberType: any = MemberType;
|
||||
|
||||
constructor(
|
||||
private authService: GrpcAuthService,
|
||||
private mgmtService: ManagementService,
|
||||
private adminService: AdminService,
|
||||
private dialog: MatDialog,
|
||||
@ -51,10 +55,17 @@ export class MembershipsComponent implements OnInit {
|
||||
}
|
||||
|
||||
public async loadManager(userId: string): Promise<void> {
|
||||
this.mgmtService.SearchUserMemberships(userId, 100, 0, []).then(response => {
|
||||
this.memberships = response.toObject();
|
||||
this.loading = false;
|
||||
});
|
||||
if (this.auth) {
|
||||
this.authService.SearchUserMemberships(100, 0, []).then(response => {
|
||||
this.memberships = response.toObject();
|
||||
this.loading = false;
|
||||
});
|
||||
} else {
|
||||
this.mgmtService.SearchUserMemberships(userId, 100, 0, []).then(response => {
|
||||
this.memberships = response.toObject();
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public navigateToObject(): void {
|
||||
|
@ -1,7 +1,6 @@
|
||||
.head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #ffffff20;
|
||||
flex-wrap: wrap;
|
||||
padding-bottom: .5rem;
|
||||
|
||||
|
@ -26,6 +26,9 @@ import {
|
||||
UpdateUserProfileRequest,
|
||||
UserAddress,
|
||||
UserEmail,
|
||||
UserMembershipSearchQuery,
|
||||
UserMembershipSearchRequest,
|
||||
UserMembershipSearchResponse,
|
||||
UserPhone,
|
||||
UserProfile,
|
||||
UserProfileView,
|
||||
@ -241,6 +244,16 @@ export class GrpcAuthService {
|
||||
);
|
||||
}
|
||||
|
||||
public SearchUserMemberships(limit: number, offset: number, queryList?: UserMembershipSearchQuery[]): Promise<UserMembershipSearchResponse> {
|
||||
const req = new UserMembershipSearchRequest();
|
||||
req.setLimit(limit);
|
||||
req.setOffset(offset);
|
||||
if (queryList) {
|
||||
req.setQueriesList(queryList);
|
||||
}
|
||||
return this.grpcService.auth.searchMyUserMemberships(req);
|
||||
}
|
||||
|
||||
public GetMyUserEmail(): Promise<UserEmail> {
|
||||
return this.grpcService.auth.getMyUserEmail(
|
||||
new Empty(),
|
||||
|
@ -55,6 +55,7 @@ export class AuthInterceptor<TReq = unknown, TResp = unknown> implements UnaryIn
|
||||
titleKey: 'ERRORS.TOKENINVALID.TITLE',
|
||||
descriptionKey: 'ERRORS.TOKENINVALID.DESCRIPTION',
|
||||
},
|
||||
disableClose: true,
|
||||
width: '400px',
|
||||
});
|
||||
|
||||
|
@ -1362,4 +1362,11 @@ export class ManagementService {
|
||||
public UpdateOIDCAppConfig(req: OIDCConfigUpdate): Promise<OIDCConfig> {
|
||||
return this.grpcService.mgmt.updateApplicationOIDCConfig(req);
|
||||
}
|
||||
|
||||
public RemoveApplication(projectId: string, appId: string): Promise<Empty> {
|
||||
const req = new ApplicationID();
|
||||
req.setId(appId);
|
||||
req.setProjectId(projectId);
|
||||
return this.grpcService.mgmt.removeApplication(req);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,29 @@
|
||||
{
|
||||
"APP_NAME": "ZITADEL",
|
||||
"ONBOARDING": {
|
||||
"HEADER":"Erste Schritte",
|
||||
"TITLE":"Lernen Sie unsere ZITADEL Console kennen.",
|
||||
"LOGINDESC":"Melden Sie sich an um Zugriff auf Funktionen von Zitadel zu erhalten",
|
||||
"LOGIN":"Anmelden",
|
||||
"DESCRIPTION":"Führen Sie die folgenden Schritte aus und passen Sie ZITADEL optimal an Ihre Bedürfnisse an.",
|
||||
"STEPS_TITLE":"Führen Sie die folgenden Schritte in gewünschter Reihenfolge aus:",
|
||||
"STEPS": {
|
||||
"1": {
|
||||
"TITLE":"Projekt erstellen",
|
||||
"DESC":"Erstellen Sie Ihr erstes Projekt und legen Sie Zugangsberechtigungen eventueller Mitarbeiter fest."
|
||||
},
|
||||
"2": {
|
||||
"TITLE":"Applikation erstellen",
|
||||
"DESC":"Erstellen Sie eine Applikation innerhalb Ihres Projektes und legen Sie dessen Eigenschaften fest."
|
||||
},
|
||||
"3": {
|
||||
"TITLE":"Sicherheit verbessern",
|
||||
"DESC":"Erweitern Sie die Zugangsrichtlinien und erhöhen Sie dadurch die Sicherheit ihrer Benutzer."
|
||||
}
|
||||
},
|
||||
"START":"Start",
|
||||
"DOCS":"Docs"
|
||||
},
|
||||
"HOME": {
|
||||
"TITLE": "ZITADEL",
|
||||
"SECURITYANDPRIVACY": "Datenschutz und Personalisierung",
|
||||
@ -32,9 +56,15 @@
|
||||
"WELCOME":"Willkommen",
|
||||
"WELCOMESENTENCE":"Hier findest Du die empfohlenen Aktionen basierend auf Deinen zuletzt erworbenen Berechtigungen. Beachte bitte, dass Du möglicherweise Deine Organisation in der Kopfzeile wechseln musst.",
|
||||
"DISCLAIMER":"Du kannst nur die Einstellungen Deiner aktuellen Organisation, die in der Kopfzeile angegeben ist, sehen. ZITADEL behandelt Deine Daten vertraulich und sicher.",
|
||||
"DISCLAIMERLINK":"Mehr Informationen zur Sicherheit"
|
||||
"DISCLAIMERLINK":"Mehr Informationen zur Sicherheit",
|
||||
"QUICKSTARTS": {
|
||||
"LABEL":"Erste Schritte",
|
||||
"TITLE":"Quickstarts",
|
||||
"DESCRIPTION":"Mit ZITADEL schnell durchstarten."
|
||||
}
|
||||
},
|
||||
"MENU": {
|
||||
"DASHBOARD":"Übersicht",
|
||||
"PERSONAL_INFO": "Persönliche Informationen",
|
||||
"DOCUMENTATION":"Dokumentation",
|
||||
"IAMPOLICIES":"IAM",
|
||||
@ -54,6 +84,7 @@
|
||||
"SHOWORGS":"Alle Organisationen anzeigen",
|
||||
"GRANTSECTION":"Berechtigungssektion",
|
||||
"GRANTS":"Berechtigungen",
|
||||
"TOC":"Datenschutz und AGB",
|
||||
"TOOLTIP": {
|
||||
"PERSONAL":"Verwalte deinen persönlichen Account, deine IDPs, Login Methoden, Faktoren und Berechtigungen",
|
||||
"IAMPOLICIES":"Verwalte ZITADELs globale Zugangsrichtlinien und verwalte ZITADEL Manager",
|
||||
@ -930,12 +961,34 @@
|
||||
"1": "Aktiv",
|
||||
"2": "Inaktiv"
|
||||
}
|
||||
},
|
||||
"DIALOG": {
|
||||
"DELETE": {
|
||||
"TITLE": "App löschen",
|
||||
"DESCRIPTION":"Wollen Sie diese App wirklich löschen?"
|
||||
}
|
||||
},
|
||||
"NEXTSTEPS": {
|
||||
"TITLE":"Nächste Schritte",
|
||||
"0": {
|
||||
"TITLE":"Rollen festlegen",
|
||||
"DESC":"Erfassen Sie Rollen für ihr Projekt"
|
||||
},
|
||||
"1": {
|
||||
"TITLE":"Benutzer hinzufügen",
|
||||
"DESC":"Fügen Sie Nutzer ihrer Organisation hinzu"
|
||||
},
|
||||
"2": {
|
||||
"TITLE":"Hilfe & Support",
|
||||
"DESC":"Lesen Sie unsere Dokumentation zum Erstellen von Applikation oder kontaktieren Sie unseren Support"
|
||||
}
|
||||
}
|
||||
},
|
||||
"NAME": "Name",
|
||||
"TYPE":"Anwendungstyp",
|
||||
"GRANT":"Berechtigungstypen",
|
||||
"OIDC": {
|
||||
"CURRENT":"Aktuelle Konfiguration",
|
||||
"TOKENSECTIONTITLE":"AuthToken Optionen",
|
||||
"REDIRECTSECTIONTITLE":"Weiterleitungseinstellungen",
|
||||
"PROSWITCH":"Konfigurator überspringen",
|
||||
@ -991,13 +1044,58 @@
|
||||
"IDTOKENROLEASSERTION_DESCRIPTION":"Bei Auswahl werden dem Id Token die Rollen des Authentifizierten Benutzers hinzugefügt.",
|
||||
"IDTOKENUSERINFOASSERTION":"User Info im ID Token",
|
||||
"IDTOKENUSERINFOASSERTION_DESCRIPTION":"Ermöglich OIDC clients claims von profile, email, phone und address direkt vom ID Token zu beziehen.",
|
||||
"CLOCKSKEW":"ermöglicht Clients, den Taktversatz von OP und Client zu verarbeiten. Die Dauer (0-5s) wird der exp addiert und von iats, auth_time und nbf abgezogen."
|
||||
"CLOCKSKEW":"ermöglicht Clients, den Taktversatz von OP und Client zu verarbeiten. Die Dauer (0-5s) wird der exp addiert und von iats, auth_time und nbf abgezogen.",
|
||||
"RECOMMENDED":"Empfohlen",
|
||||
"NOTRECOMMENDED":"nicht empfohlen",
|
||||
"SELECTION":{
|
||||
"APPTYPE": {
|
||||
"WEB": {
|
||||
"TITLE":"Web",
|
||||
"DESCRIPTION":"Standard Web applications wie .net, PHP, Node.js, Java, etc."
|
||||
},
|
||||
"NATIVE": {
|
||||
"TITLE":"NATIVE",
|
||||
"DESCRIPTION":"Mobile Apps, Desktop, Smart Devices, etc."
|
||||
},
|
||||
"USERAGENT": {
|
||||
"TITLE":"User Agent",
|
||||
"DESCRIPTION":"Single Page Applications (SPA) und grundsätzlich alle im Browser aufgeführten JS Frameworks"
|
||||
}
|
||||
},
|
||||
"AUTHMETHOD": {
|
||||
"CODE": {
|
||||
"TITLE":"Code",
|
||||
"DESCRIPTION":"Tausche den Authorization Code gegen Tokens ein"
|
||||
},
|
||||
"PKCE": {
|
||||
"TITLE":"PKCE",
|
||||
"DESCRIPTION":"Nutze einen Zufalls Hash Wert anstelle des Client Secret für mehr Sicherheit"
|
||||
},
|
||||
"POST": {
|
||||
"TITLE":"POST",
|
||||
"DESCRIPTION":"Sende client_id und client_secret im (HTML) Formular"
|
||||
},
|
||||
"PK_JWT": {
|
||||
"TITLE":"Private Key JWT",
|
||||
"DESCRIPTION":"Nutze einen Private Key um deine Application zu authentifizieren"
|
||||
},
|
||||
"IMPLICIT": {
|
||||
"TITLE":"Implicit",
|
||||
"DESCRIPTION":"Erhalte die Token direkt vom authorize Endpoint"
|
||||
},
|
||||
"CUSTOM": {
|
||||
"TITLE":"Custom",
|
||||
"DESCRIPTION":"Deine Konfiguration entspricht keiner anderen Option."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"TOAST": {
|
||||
"REACTIVATED":"Anwendung reaktiviert.",
|
||||
"DEACTIVATED":"Anwendung deaktiviert.",
|
||||
"OIDCUPDATED":"OIDC-Konfiguration geändert.",
|
||||
"OIDCCLIENTSECRETREGENERATED":"OIDC-Client Secret generiert."
|
||||
"OIDCCLIENTSECRETREGENERATED":"OIDC-Client Secret generiert.",
|
||||
"DELETED":"App gelöscht."
|
||||
}
|
||||
},
|
||||
"GENDERS": {
|
||||
|
@ -1,5 +1,29 @@
|
||||
{
|
||||
"APP_NAME": "ZITADEL",
|
||||
"ONBOARDING": {
|
||||
"HEADER":"First Steps",
|
||||
"TITLE":"Learn how to use ZITADEL",
|
||||
"LOGINDESC":"You need to log in to control your ZITADEL settings.",
|
||||
"LOGIN":"Login",
|
||||
"DESCRIPTION":"We at ZITADEL care a lot about security and performance. Carry out the following steps and adapt ZITADEL optimally to your needs.",
|
||||
"STEPS_TITLE":"Complete the following steps in the order you want:",
|
||||
"STEPS": {
|
||||
"1": {
|
||||
"TITLE":"Create a project",
|
||||
"DESC":"Create your first project and define access rights for any employees."
|
||||
},
|
||||
"2": {
|
||||
"TITLE":"Create Application",
|
||||
"DESC":"Create an application within your project and define its properties."
|
||||
},
|
||||
"3": {
|
||||
"TITLE":"Improve security",
|
||||
"DESC":"Extend the access policies and thereby increase the security of your users."
|
||||
}
|
||||
},
|
||||
"START":"Start",
|
||||
"DOCS":"Docs"
|
||||
},
|
||||
"HOME": {
|
||||
"TITLE": "ZITADEL",
|
||||
"SECURITYANDPRIVACY": "Data Protection and Personalisation",
|
||||
@ -32,9 +56,15 @@
|
||||
"WELCOME":"Welcome",
|
||||
"WELCOMESENTENCE":"Here you can find recommended actions based on your last acquired permissions. Note that you may have to select your organisation in the header above.",
|
||||
"DISCLAIMER":"You can only see settings of your current organisation specified in the header. ZITADEL treats your data confidentially and securely.",
|
||||
"DISCLAIMERLINK":"Further information"
|
||||
"DISCLAIMERLINK":"Further information",
|
||||
"QUICKSTARTS": {
|
||||
"LABEL":"First Steps",
|
||||
"TITLE":"Quickstarts",
|
||||
"DESCRIPTION":"Get started with ZITADEL quickly."
|
||||
}
|
||||
},
|
||||
"MENU": {
|
||||
"DASHBOARD":"Overview",
|
||||
"PERSONAL_INFO": "Personal Information",
|
||||
"DOCUMENTATION":"Documentation",
|
||||
"IAMPOLICIES":"IAM",
|
||||
@ -54,6 +84,7 @@
|
||||
"SHOWORGS":"Show All Organisations",
|
||||
"GRANTSECTION":"Authorization Section",
|
||||
"GRANTS":"Authorizations",
|
||||
"TOC":"Privacy Policy and TOC",
|
||||
"TOOLTIP": {
|
||||
"PERSONAL":"Show your Personal Account, your IDPs, Login methods, Factors and Authorisations",
|
||||
"IAMPOLICIES":"Manage ZITADELs global Access policies und elect ZITADEL Managers",
|
||||
@ -930,12 +961,34 @@
|
||||
"1": "Active",
|
||||
"2": "Inactive"
|
||||
}
|
||||
},
|
||||
"DIALOG": {
|
||||
"DELETE": {
|
||||
"TITLE": "Delete App",
|
||||
"DESCRIPTION":"Do you really want to delete this application?"
|
||||
}
|
||||
},
|
||||
"NEXTSTEPS": {
|
||||
"TITLE":"Next Steps",
|
||||
"0": {
|
||||
"TITLE":"Add roles",
|
||||
"DESC":"Enter your project roles"
|
||||
},
|
||||
"1": {
|
||||
"TITLE":"Add users",
|
||||
"DESC":"Add new users of your organization"
|
||||
},
|
||||
"2": {
|
||||
"TITLE":"Help & Support",
|
||||
"DESC":"Read our documentation on creating applications or contact our support"
|
||||
}
|
||||
}
|
||||
},
|
||||
"NAME": "Name",
|
||||
"TYPE":"Application Type",
|
||||
"GRANT":"Grant Types",
|
||||
"OIDC": {
|
||||
"CURRENT":"Current Config",
|
||||
"TOKENSECTIONTITLE":"AuthToken Options",
|
||||
"REDIRECTSECTIONTITLE":"Redirect Settings",
|
||||
"PROSWITCH":"I'm a pro. Skip this wizard.",
|
||||
@ -991,13 +1044,58 @@
|
||||
"IDTOKENROLEASSERTION_DESCRIPTION":"If selected, the roles of the authenticated user are added to the ID token.",
|
||||
"IDTOKENUSERINFOASSERTION":"User Info inside ID Token",
|
||||
"IDTOKENUSERINFOASSERTION_DESCRIPTION":"Enables clients to retrieve profile, email, phone and address claims from ID token.",
|
||||
"CLOCKSKEW":"Enables clients to handle clock skew of OP and client. The duration (0-5s) will be added to exp claim and subtracted from iats, auth_time and nbf."
|
||||
"CLOCKSKEW":"Enables clients to handle clock skew of OP and client. The duration (0-5s) will be added to exp claim and subtracted from iats, auth_time and nbf.",
|
||||
"RECOMMENDED":"recommended",
|
||||
"NOTRECOMMENDED":"not recommended",
|
||||
"SELECTION":{
|
||||
"APPTYPE": {
|
||||
"WEB": {
|
||||
"TITLE":"Web",
|
||||
"DESCRIPTION":"Regular Web applications like .net, PHP, Node.js, Java, etc."
|
||||
},
|
||||
"NATIVE": {
|
||||
"TITLE":"NATIVE",
|
||||
"DESCRIPTION":"Mobile Apps, Desktop, Smart Devices, etc."
|
||||
},
|
||||
"USERAGENT": {
|
||||
"TITLE":"User Agent",
|
||||
"DESCRIPTION":"Single Page Applications (SPA) and in general all JS frameworks executed in browsers"
|
||||
}
|
||||
},
|
||||
"AUTHMETHOD": {
|
||||
"CODE": {
|
||||
"TITLE":"Code",
|
||||
"DESCRIPTION":"Exchange the authorization code for the tokens"
|
||||
},
|
||||
"PKCE": {
|
||||
"TITLE":"PKCE",
|
||||
"DESCRIPTION":"Use a random hash instead of a static client secret for more security"
|
||||
},
|
||||
"POST": {
|
||||
"TITLE":"POST",
|
||||
"DESCRIPTION":"Send client_id and client_secret as part of the form"
|
||||
},
|
||||
"PK_JWT": {
|
||||
"TITLE":"Private Key JWT",
|
||||
"DESCRIPTION":"Use a private key to authorize your application"
|
||||
},
|
||||
"IMPLICIT": {
|
||||
"TITLE":"Implicit",
|
||||
"DESCRIPTION":"Get the tokens directly from the authorization endpoint"
|
||||
},
|
||||
"CUSTOM": {
|
||||
"TITLE":"Custom",
|
||||
"DESCRIPTION":"Your setting doesn't correspond to any other option."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"TOAST": {
|
||||
"REACTIVATED":"Application reactivated.",
|
||||
"DEACTIVATED":"Application deactivated.",
|
||||
"OIDCUPDATED":"OIDC configuration updated.",
|
||||
"OIDCCLIENTSECRETREGENERATED":"OIDC client secret generated."
|
||||
"OIDCCLIENTSECRETREGENERATED":"OIDC client secret generated.",
|
||||
"DELETED":"App deleted."
|
||||
}
|
||||
},
|
||||
"GENDERS": {
|
||||
|
76
console/src/assets/images/zitadel-logo-solo-dark.svg
Normal file
76
console/src/assets/images/zitadel-logo-solo-dark.svg
Normal file
@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 467 468" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,0,-492)">
|
||||
<g id="zitadel-logo-solo-lightdesign" transform="matrix(0.564847,0,0,0.659318,-1282.85,492.925)">
|
||||
<rect x="2271.15" y="0" width="826.773" height="708.241" style="fill:none;"/>
|
||||
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5923.46,-2258.26)">
|
||||
<path d="M1493.5,1056.38L1493.5,1037L1496.5,1037L1496.5,1061.62L1426.02,1020.38L1496.5,979.392L1496.5,1004L1493.5,1004L1493.5,984.608L1431.98,1020.39L1493.5,1056.38Z" style="fill:rgb(35,35,35);"/>
|
||||
</g>
|
||||
<g transform="matrix(31.0036,0,0,15.0393,-397275,-666.457)">
|
||||
<g transform="matrix(-0.0429306,-0.282967,0.160219,-0.0758207,12884.5,137.392)">
|
||||
<path d="M212.517,110L200.392,110L190,92L179.608,110L167.483,110L190,71L212.517,110Z" style="fill:url(#_Linear1);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.160219,0.0758207,-0.0429306,0.282967,12878.9,10.8747)">
|
||||
<path d="M212.517,110L200.392,110L190,92L179.608,110L167.483,110L190,71L212.517,110Z" style="fill:url(#_Linear2);"/>
|
||||
</g>
|
||||
<g transform="matrix(-0.117289,0.207146,-0.117289,-0.207146,12943.8,65.7)">
|
||||
<path d="M212.517,110L200.392,110L190,92L179.608,110L167.483,110L190,71L212.517,110Z" style="fill:url(#_Linear3);"/>
|
||||
</g>
|
||||
<g transform="matrix(-0.160219,-0.0758207,0.0429306,-0.282967,12917.4,132.195)">
|
||||
<path d="M139.622,117L149,142L130.244,142L139.622,117Z" style="fill:url(#_Linear4);"/>
|
||||
</g>
|
||||
<g transform="matrix(-0.117289,0.207146,0.117289,0.207146,12897.8,5.87512)">
|
||||
<path d="M139.622,117L149,142L130.244,142L139.622,117Z" style="fill:url(#_Linear5);"/>
|
||||
</g>
|
||||
<g transform="matrix(-0.0429306,-0.282967,-0.160219,0.0758207,12936.8,97.6441)">
|
||||
<path d="M139.622,117L149,142L130.244,142L139.622,117Z" style="fill:url(#_Linear6);"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5928.43,-2257.12)">
|
||||
<circle cx="1496" cy="1004" r="7" style="fill:rgb(35,35,35);"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5884.5,-2116.69)">
|
||||
<circle cx="1496" cy="1004" r="7" style="fill:rgb(35,35,35);"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5855.22,-2023.06)">
|
||||
<circle cx="1496" cy="1004" r="7" style="fill:rgb(35,35,35);"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-6234.47,-2112.14)">
|
||||
<circle cx="1496" cy="1004" r="7" style="fill:rgb(35,35,35);"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5957.71,-2350.75)">
|
||||
<circle cx="1496" cy="1004" r="7" style="fill:rgb(35,35,35);"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5477.99,-831.33)">
|
||||
<path d="M1499.26,757.787C1499.26,757.787 1497.37,756.489 1497,755.2C1496.71,754.182 1496.57,750.662 1496.54,750C1496.41,747.303 1499.21,745.644 1499.21,745.644L1490.01,745.835C1490.01,745.835 1493.15,745.713 1493.46,750C1493.51,750.661 1493.23,753.476 1493,755.2C1492.91,756.447 1491.2,757.668 1491.2,757.668L1499.26,757.787Z" style="fill:rgb(35,35,35);"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5404.79,-597.271)">
|
||||
<path d="M1495,760L1495,744" style="fill:none;"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5404.79,-597.271)">
|
||||
<path d="M1498.27,757.077C1498.27,757.077 1496.71,756.46 1496.65,754.8C1496.65,753.658 1496.64,753.281 1496.65,752.016C1496.62,751.334 1496.59,750.608 1496.65,749.949C1496.78,746.836 1498.5,746.156 1498.5,746.156L1491.46,745.931C1491.46,745.931 1493.37,746.719 1493.65,749.83C1493.71,750.489 1493.69,751.528 1493.65,752.209C1493.64,753.331 1493.64,753.413 1493.65,754.518C1493.68,756.334 1492.58,756.827 1492.58,756.827L1498.27,757.077Z" style="fill:rgb(35,35,35);"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5770.62,-677.495)">
|
||||
<path d="M1496.17,759.473L1555.54,720.014" style="fill:none;"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5770.62,-677.495)">
|
||||
<path d="M1500.86,762.056C1500.86,762.056 1499.86,760.4 1503.09,757.456C1504.91,755.797 1507.33,754.151 1509.98,752.255C1514.82,748.79 1520.68,744.94 1526.52,741.049C1531.45,737.766 1536.38,734.479 1540.82,731.68C1544.52,729.349 1547.85,727.296 1550.54,725.8C1551.07,725.506 1551.6,725.329 1552.05,725.029C1554.73,723.257 1556.85,724.968 1556.85,724.968L1552.23,716.282C1552.23,716.282 1551.99,719.454 1550,720.997C1549.57,721.333 1549.15,721.741 1548.67,722.12C1546.2,724.053 1542.99,726.344 1539.39,728.867C1535.06,731.898 1530.13,735.166 1525.19,738.438C1519.35,742.314 1513.52,746.234 1508.49,749.329C1505.74,751.023 1503.28,752.577 1501.13,753.598C1497.99,755.086 1495.28,753.617 1495.28,753.617L1500.86,762.056Z" style="fill:rgb(35,35,35);"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,-1.16463,-3.72366,-3997,4993.28)">
|
||||
<path d="M1496.17,759.473L1555.54,720.014" style="fill:none;"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,-1.16463,-3.72366,-3997,4993.28)">
|
||||
<path d="M1496.1,754.362C1496.1,754.362 1497.2,755.607 1501.13,753.598C1503.25,752.509 1505.74,751.023 1508.49,749.329C1513.52,746.234 1519.35,742.314 1525.19,738.438C1530.13,735.166 1534.94,731.832 1539.27,728.802C1542.87,726.279 1549.36,722.059 1549.81,721.75C1552.75,719.73 1552.18,718.196 1552.18,718.196L1555.28,724.152C1555.28,724.152 1553.77,722.905 1551.37,724.681C1550.93,725.006 1544.52,729.349 1540.82,731.68C1536.38,734.479 1531.45,737.766 1526.52,741.049C1520.68,744.94 1514.82,748.79 1509.98,752.255C1507.33,754.151 1504.89,755.771 1503.09,757.456C1499.47,760.841 1501.26,763.283 1501.26,763.283L1496.1,754.362Z" style="fill:rgb(35,35,35);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-41.5984,155.247,-155.247,-41.5984,201.516,76.8392)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(155.247,-41.5984,41.5984,155.247,110.08,195.509)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear3" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-113.649,-113.649,113.649,-113.649,258.31,215.618)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear4" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-155.247,41.5984,-41.5984,-155.247,220.914,144.546)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear5" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-113.649,113.649,113.649,113.649,206.837,124.661)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear6" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-41.5984,-155.247,-155.247,41.5984,152.054,262.8)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 8.5 KiB |
74
console/src/assets/images/zitadel-logo-solo-light.svg
Normal file
74
console/src/assets/images/zitadel-logo-solo-light.svg
Normal file
@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 467 467" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g id="zitadel-logo-solo-darkdesign" transform="matrix(0.564847,0,0,0.659318,-1282.85,0)">
|
||||
<rect x="2271.15" y="0" width="826.773" height="708.241" style="fill:none;"/>
|
||||
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5923.46,-2258.26)">
|
||||
<path d="M1493.5,1056.38L1493.5,1037L1496.5,1037L1496.5,1061.62L1426.02,1020.38L1496.5,979.392L1496.5,1004L1493.5,1004L1493.5,984.608L1431.98,1020.39L1493.5,1056.38Z" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(31.0036,0,0,15.0393,-397275,-666.457)">
|
||||
<g transform="matrix(-0.0429306,-0.282967,0.160219,-0.0758207,12884.5,137.392)">
|
||||
<path d="M212.517,110L200.392,110L190,92L179.608,110L167.483,110L190,71L212.517,110Z" style="fill:url(#_Linear1);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.160219,0.0758207,-0.0429306,0.282967,12878.9,10.8747)">
|
||||
<path d="M212.517,110L200.392,110L190,92L179.608,110L167.483,110L190,71L212.517,110Z" style="fill:url(#_Linear2);"/>
|
||||
</g>
|
||||
<g transform="matrix(-0.117289,0.207146,-0.117289,-0.207146,12943.8,65.7)">
|
||||
<path d="M212.517,110L200.392,110L190,92L179.608,110L167.483,110L190,71L212.517,110Z" style="fill:url(#_Linear3);"/>
|
||||
</g>
|
||||
<g transform="matrix(-0.160219,-0.0758207,0.0429306,-0.282967,12917.4,132.195)">
|
||||
<path d="M139.622,117L149,142L130.244,142L139.622,117Z" style="fill:url(#_Linear4);"/>
|
||||
</g>
|
||||
<g transform="matrix(-0.117289,0.207146,0.117289,0.207146,12897.8,5.87512)">
|
||||
<path d="M139.622,117L149,142L130.244,142L139.622,117Z" style="fill:url(#_Linear5);"/>
|
||||
</g>
|
||||
<g transform="matrix(-0.0429306,-0.282967,-0.160219,0.0758207,12936.8,97.6441)">
|
||||
<path d="M139.622,117L149,142L130.244,142L139.622,117Z" style="fill:url(#_Linear6);"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5928.43,-2257.12)">
|
||||
<circle cx="1496" cy="1004" r="7" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5884.5,-2116.69)">
|
||||
<circle cx="1496" cy="1004" r="7" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5855.22,-2023.06)">
|
||||
<circle cx="1496" cy="1004" r="7" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-6234.47,-2112.14)">
|
||||
<circle cx="1496" cy="1004" r="7" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5957.71,-2350.75)">
|
||||
<circle cx="1496" cy="1004" r="7" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5477.99,-831.33)">
|
||||
<path d="M1499.26,757.787C1499.26,757.787 1497.37,756.489 1497,755.2C1496.71,754.182 1496.57,750.662 1496.54,750C1496.41,747.303 1499.21,745.644 1499.21,745.644L1490.01,745.835C1490.01,745.835 1493.15,745.713 1493.46,750C1493.51,750.661 1493.23,753.476 1493,755.2C1492.91,756.447 1491.2,757.668 1491.2,757.668L1499.26,757.787Z" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5404.79,-597.271)">
|
||||
<path d="M1495,760L1495,744" style="fill:none;"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5404.79,-597.271)">
|
||||
<path d="M1498.27,757.077C1498.27,757.077 1496.71,756.46 1496.65,754.8C1496.65,753.658 1496.64,753.281 1496.65,752.016C1496.62,751.334 1496.59,750.608 1496.65,749.949C1496.78,746.836 1498.5,746.156 1498.5,746.156L1491.46,745.931C1491.46,745.931 1493.37,746.719 1493.65,749.83C1493.71,750.489 1493.69,751.528 1493.65,752.209C1493.64,753.331 1493.64,753.413 1493.65,754.518C1493.68,756.334 1492.58,756.827 1492.58,756.827L1498.27,757.077Z" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5770.62,-677.495)">
|
||||
<path d="M1496.17,759.473L1555.54,720.014" style="fill:none;"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5770.62,-677.495)">
|
||||
<path d="M1500.86,762.056C1500.86,762.056 1499.86,760.4 1503.09,757.456C1504.91,755.797 1507.33,754.151 1509.98,752.255C1514.82,748.79 1520.68,744.94 1526.52,741.049C1531.45,737.766 1536.38,734.479 1540.82,731.68C1544.52,729.349 1547.85,727.296 1550.54,725.8C1551.07,725.506 1551.6,725.329 1552.05,725.029C1554.73,723.257 1556.85,724.968 1556.85,724.968L1552.23,716.282C1552.23,716.282 1551.99,719.454 1550,720.997C1549.57,721.333 1549.15,721.741 1548.67,722.12C1546.2,724.053 1542.99,726.344 1539.39,728.867C1535.06,731.898 1530.13,735.166 1525.19,738.438C1519.35,742.314 1513.52,746.234 1508.49,749.329C1505.74,751.023 1503.28,752.577 1501.13,753.598C1497.99,755.086 1495.28,753.617 1495.28,753.617L1500.86,762.056Z" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,-1.16463,-3.72366,-3997,4993.28)">
|
||||
<path d="M1496.17,759.473L1555.54,720.014" style="fill:none;"/>
|
||||
</g>
|
||||
<g transform="matrix(4.96737,-1.14029,-1.16463,-3.72366,-3997,4993.28)">
|
||||
<path d="M1496.1,754.362C1496.1,754.362 1497.2,755.607 1501.13,753.598C1503.25,752.509 1505.74,751.023 1508.49,749.329C1513.52,746.234 1519.35,742.314 1525.19,738.438C1530.13,735.166 1534.94,731.832 1539.27,728.802C1542.87,726.279 1549.36,722.059 1549.81,721.75C1552.75,719.73 1552.18,718.196 1552.18,718.196L1555.28,724.152C1555.28,724.152 1553.77,722.905 1551.37,724.681C1550.93,725.006 1544.52,729.349 1540.82,731.68C1536.38,734.479 1531.45,737.766 1526.52,741.049C1520.68,744.94 1514.82,748.79 1509.98,752.255C1507.33,754.151 1504.89,755.771 1503.09,757.456C1499.47,760.841 1501.26,763.283 1501.26,763.283L1496.1,754.362Z" style="fill:white;"/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-41.5984,155.247,-155.247,-41.5984,201.516,76.8392)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(155.247,-41.5984,41.5984,155.247,110.08,195.509)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear3" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-113.649,-113.649,113.649,-113.649,258.31,215.618)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear4" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-155.247,41.5984,-41.5984,-155.247,220.914,144.546)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear5" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-113.649,113.649,113.649,113.649,206.837,124.661)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear6" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-41.5984,-155.247,-155.247,41.5984,152.054,262.8)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 8.1 KiB |
@ -5,24 +5,29 @@
|
||||
@import './styles/link.scss';
|
||||
@import './styles/sidenav-list';
|
||||
@import 'src/app/modules/avatar/avatar.component';
|
||||
@import 'src/app/modules/app-radio/app-type-radio/app-type-radio.component';
|
||||
@import 'src/app/modules/app-radio/app-auth-method-radio/app-auth-method-radio.component';
|
||||
@import 'src/app/modules/changes/changes.component';
|
||||
@import 'src/app/modules/info-section/info-section.component';
|
||||
@import 'src/app/modules/detail-layout/detail-layout.component';
|
||||
@import 'src/app/pages/projects/owned-projects/owned-project-detail/application-grid/application-grid.component';
|
||||
@import 'src/app/modules/app-card/app-card.component';
|
||||
@import 'src/app/pages/users/user-detail/auth-user-detail/theme-setting/theme-card';
|
||||
@import 'src/app/pages/users/user-detail/memberships/memberships.component';
|
||||
@import 'src/app/app.component.scss';
|
||||
@import 'src/app/modules/form-field/form-field.component.scss';
|
||||
@import 'src/app/modules/label/label.component.scss';
|
||||
@import 'src/app/modules/meta-layout/meta.scss';
|
||||
@import 'src/app/modules/onboarding/onboarding.component.scss';
|
||||
|
||||
@mixin component-themes($theme) {
|
||||
@include avatar-theme($theme);
|
||||
@include app-type-radio-theme($theme);
|
||||
@include app-auth-method-radio-theme($theme);
|
||||
@include card-theme($theme);
|
||||
@include table-theme($theme);
|
||||
@include detail-layout-theme($theme);
|
||||
@include sidenav-list-theme($theme);
|
||||
@include application-grid-theme($theme);
|
||||
@include app-card-theme($theme);
|
||||
@include membership-theme($theme);
|
||||
@include changes-theme($theme);
|
||||
@include theme-card($theme);
|
||||
@ -34,4 +39,5 @@
|
||||
@include link-theme($theme);
|
||||
@include meta-theme($theme);
|
||||
@include info-section-theme($theme);
|
||||
@include onboarding-theme($theme);
|
||||
}
|
||||
|
@ -219,18 +219,21 @@ $custom-typography:
|
||||
box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
|
||||
background-color: #2d2e30;
|
||||
border-radius: 8px;
|
||||
transition: all .3s cubic-bezier(.645, .045, .355, 1) !important;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background-color: #2d2e30;
|
||||
transition: all .3s cubic-bezier(.645, .045, .355, 1) !important;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #737c8870;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all .3s cubic-bezier(.645, .045, .355, 1) !important;
|
||||
}
|
||||
|
||||
.root-header {
|
||||
|
@ -16,18 +16,23 @@
|
||||
box-shadow: inset 1px 0 if($is-dark-theme, #303131, #e3e8ee);
|
||||
}
|
||||
|
||||
.sidenav {
|
||||
box-shadow: inset -1px 0 if($is-dark-theme, #303131, #e3e8ee);
|
||||
transition: all .3s cubic-bezier(.645, .045, .355, 1) !important;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
color: mat-color($foreground, text) !important;
|
||||
|
||||
&:hover {
|
||||
background-color: $sec-dark;
|
||||
background-color: if($is-dark-theme, $sec-dark, rgb(84 105 212 / 6%));
|
||||
border-top-right-radius: 1.5rem;
|
||||
border-bottom-right-radius: 1.5rem;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $primary-color !important;
|
||||
background-color: rgba($color: $primary-color, $alpha: .1) !important;
|
||||
background-color: if($is-dark-theme, rgba($color: $primary-color, $alpha: .1), rgb(84 105 212 / 6%)) !important;
|
||||
}
|
||||
|
||||
.c_label {
|
||||
@ -54,7 +59,16 @@
|
||||
.root-header {
|
||||
box-shadow: inset 0 -1px #e3e8ee;
|
||||
background-color: $primary-dark !important;
|
||||
transition: background-color .3s cubic-bezier(.645, .045, .355, 1);
|
||||
transition: all .3s cubic-bezier(.645, .045, .355, 1);
|
||||
|
||||
.slash {
|
||||
color: if($is-dark-theme, #525454, #d1d5d9);
|
||||
}
|
||||
|
||||
.org-button {
|
||||
border: 1px solid if($is-dark-theme, #303131, #e3e8ee);
|
||||
transition: all .3s cubic-bezier(.645, .045, .355, 1) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-line {
|
||||
@ -63,7 +77,7 @@
|
||||
align-items: center;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: calc(100vw - 300px);
|
||||
right: calc(100vw - 280px);
|
||||
background-color: $primary-color;
|
||||
color: white;
|
||||
z-index: 1;
|
||||
|
@ -64,7 +64,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
.mat-checkbox {
|
||||
td .mat-checkbox,
|
||||
th .mat-checkbox {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
|
6
go.mod
6
go.mod
@ -16,7 +16,7 @@ require (
|
||||
github.com/allegro/bigcache v1.2.1
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc
|
||||
github.com/caos/logging v0.0.2
|
||||
github.com/caos/oidc v0.13.2
|
||||
github.com/caos/oidc v0.14.0
|
||||
github.com/caos/orbos v1.5.14-0.20210205131708-6dc812182dc0
|
||||
github.com/cockroachdb/cockroach-go/v2 v2.1.0
|
||||
github.com/duo-labs/webauthn v0.0.0-20200714211715-1daaee874e43
|
||||
@ -56,7 +56,7 @@ require (
|
||||
github.com/rs/cors v1.7.0
|
||||
github.com/sony/sonyflake v1.0.0
|
||||
github.com/spf13/cobra v0.0.7
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 // indirect
|
||||
github.com/ttacon/libphonenumber v1.1.0
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.13.0
|
||||
@ -69,7 +69,7 @@ require (
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 // indirect
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect
|
||||
golang.org/x/text v0.3.4
|
||||
golang.org/x/text v0.3.5
|
||||
golang.org/x/tools v0.0.0-20201103235415-b653051172e4
|
||||
google.golang.org/api v0.34.0
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
|
53
go.sum
53
go.sum
@ -108,6 +108,7 @@ github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKS
|
||||
github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
@ -116,6 +117,7 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
@ -124,6 +126,7 @@ github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQ
|
||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.31.12/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJyXg=
|
||||
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
@ -137,12 +140,8 @@ github.com/caos/logging v0.0.0-20191210002624-b3260f690a6a/go.mod h1:9LKiDE2ChuG
|
||||
github.com/caos/logging v0.0.2 h1:ebg5C/HN0ludYR+WkvnFjwSExF4wvyiWPyWGcKMYsoo=
|
||||
github.com/caos/logging v0.0.2/go.mod h1:9LKiDE2ChuGv6CHYif/kiugrfEXu9AwDiFWSreX7Wp0=
|
||||
github.com/caos/oidc v0.6.2/go.mod h1:ozoi3b+aY33gzdvjz4w90VZShIHGsmDa0goruuV0arQ=
|
||||
github.com/caos/oidc v0.13.2 h1:52oP3KB1UrZuwraBTLuwM9ItRIhJQMYOm1J5uQ0sYXw=
|
||||
github.com/caos/oidc v0.13.2/go.mod h1:dLvfYUiAt9ORfl77L/KkcWuR/N0ll8Ry1nD2ERsamDY=
|
||||
github.com/caos/orbos v1.5.14-0.20210128140136-842933949472 h1:iti4tAKxBknjJkQcDKWaxlj9Jbng5kz5TpQzzyda49o=
|
||||
github.com/caos/orbos v1.5.14-0.20210128140136-842933949472/go.mod h1:ZLxNgPuYIlSvr80trezGGUIXng9gY2hHEdky/m0B/P0=
|
||||
github.com/caos/orbos v1.5.14-0.20210202122121-ad32524ffc73 h1:usYmCT11HvwxBCk1+DSCmEU6CVYhzY8jHaQHSJMrxlg=
|
||||
github.com/caos/orbos v1.5.14-0.20210202122121-ad32524ffc73/go.mod h1:ZLxNgPuYIlSvr80trezGGUIXng9gY2hHEdky/m0B/P0=
|
||||
github.com/caos/oidc v0.14.0 h1:l7mTqYDpqNRZF9Vwzq5KAQd1wQCThdceL5HpsEMGoao=
|
||||
github.com/caos/oidc v0.14.0/go.mod h1:CPsubVrA110OyLnCKwVZjTdsAVwq67DTbYIvux7UgbY=
|
||||
github.com/caos/orbos v1.5.14-0.20210205131708-6dc812182dc0 h1:N+KYBwuQO3QPr/nTUaNwjAetjp3NU4MP8Nv9Iue53UE=
|
||||
github.com/caos/orbos v1.5.14-0.20210205131708-6dc812182dc0/go.mod h1:ZLxNgPuYIlSvr80trezGGUIXng9gY2hHEdky/m0B/P0=
|
||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||
@ -154,9 +153,11 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
|
||||
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
@ -186,13 +187,17 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7 h1:6pwm8kMQKCmgUg0ZHTm5+/YvRK0s3THD/28+T6/kk4A=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
|
||||
github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ=
|
||||
github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
@ -212,6 +217,7 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
@ -224,23 +230,28 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I=
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
|
||||
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
|
||||
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fxamacker/cbor/v2 v2.2.0 h1:6eXqdDDe588rSYAi1HfZKbx6YYQO4mxQ9eC6xYpU/JQ=
|
||||
github.com/fxamacker/cbor/v2 v2.2.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
|
||||
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
@ -298,6 +309,7 @@ github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+
|
||||
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
|
||||
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
@ -308,6 +320,7 @@ github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@ -367,8 +380,10 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0 h1:wCKgOCHuUEVfsaQLpPSJb7VdYCdTVZQAuOdYm1yc/60=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
@ -383,6 +398,8 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
@ -390,6 +407,7 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsC
|
||||
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk=
|
||||
github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
|
||||
github.com/googleinterns/cloud-operations-api-mock v0.0.0-20200709193332-a1e58c29bdd3 h1:eHv/jVY/JNop1xg2J9cBb4EzyMpWZoNCP1BslSAIkOI=
|
||||
github.com/googleinterns/cloud-operations-api-mock v0.0.0-20200709193332-a1e58c29bdd3/go.mod h1:h/KNeRx7oYU4SpA4SoY7W2/NxDKEEVuwA6j9A27L4OI=
|
||||
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
@ -442,7 +460,9 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ=
|
||||
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
|
||||
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
@ -455,6 +475,7 @@ github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/inconshreveable/log15 v0.0.0-20200109203555-b30bc20e4fd1 h1:KUDFlmBg2buRWNzIcwLlKvfcnujcHQRQ1As1LoaCLAM=
|
||||
github.com/inconshreveable/log15 v0.0.0-20200109203555-b30bc20e4fd1/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||
@ -510,6 +531,7 @@ github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBef
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.1 h1:g39TucaRWyV3dwDO++eEc6qf8TVIQ/Da48WmqjZ3i7E=
|
||||
github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
|
||||
@ -523,6 +545,7 @@ github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
|
||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU=
|
||||
@ -553,8 +576,11 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/landoop/tableprinter v0.0.0-20200805134727-ea32388e35c1/go.mod h1:f0X1c0za3TbET/rl5ThtCSel0+G3/yZ8iuU9BxnyVK0=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
@ -602,6 +628,7 @@ github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
@ -644,6 +671,7 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.1.1 h1:ATCOanRDlrfKVB4WHAdJnLEqZtDmKYsweqsOUYflnBU=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.1.1/go.mod h1:d++QJC9ZVf7pa48qrsRWhMJ5pSHIPmS3OLqK1niyLxs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
@ -653,9 +681,11 @@ github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FW
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
@ -792,6 +822,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
@ -908,6 +940,7 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
@ -1053,6 +1086,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@ -1154,6 +1189,7 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
@ -1231,9 +1267,11 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||
@ -1246,9 +1284,11 @@ gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w
|
||||
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg=
|
||||
gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98=
|
||||
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0 h1:ivZFOIltbce2Mo8IjzUHAFoq/IylO9WHhNOAJK+LsJg=
|
||||
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
|
||||
gopkg.in/src-d/go-git.v4 v4.13.1 h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE=
|
||||
gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
@ -1301,6 +1341,7 @@ k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUc
|
||||
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
|
||||
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
|
||||
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 h1:Oh3Mzx5pJ+yIumsAD0MOECPVeXsVot0UkiaCGVyfGQY=
|
||||
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
|
||||
k8s.io/kubectl v0.18.3/go.mod h1:k/EpvXBDgEsHBzWr0A44l9+ArvYi3txBBnzXBjQasUQ=
|
||||
k8s.io/metrics v0.18.3/go.mod h1:TkuJE3ezDZ1ym8pYkZoEzJB7HDiFE7qxl+EmExEBoPA=
|
||||
|
@ -37,6 +37,27 @@ type Grant struct {
|
||||
Roles []string
|
||||
}
|
||||
|
||||
type Memberships []*Membership
|
||||
|
||||
type Membership struct {
|
||||
MemberType MemberType
|
||||
AggregateID string
|
||||
//ObjectID differs from aggregate id if obejct is sub of an aggregate
|
||||
ObjectID string
|
||||
|
||||
Roles []string
|
||||
}
|
||||
|
||||
type MemberType int32
|
||||
|
||||
const (
|
||||
MemberTypeUnspecified MemberType = iota
|
||||
MemberTypeOrganisation
|
||||
MemberTypeProject
|
||||
MemberTypeProjectGrant
|
||||
MemberTypeIam
|
||||
)
|
||||
|
||||
func VerifyTokenAndCreateCtxData(ctx context.Context, token, orgID string, t *TokenVerifier, method string) (_ CtxData, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
@ -2,7 +2,6 @@ package authz
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
)
|
||||
@ -16,41 +15,43 @@ func getUserMethodPermissions(ctx context.Context, t *TokenVerifier, requiredPer
|
||||
}
|
||||
|
||||
ctx = context.WithValue(ctx, dataKey, ctxData)
|
||||
grant, err := t.ResolveGrant(ctx)
|
||||
memberships, err := t.SearchMyMemberships(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if grant == nil {
|
||||
if len(memberships) == 0 {
|
||||
return requestedPermissions, nil, nil
|
||||
}
|
||||
requestedPermissions, allPermissions = mapGrantToPermissions(requiredPerm, grant, authConfig)
|
||||
requestedPermissions, allPermissions = mapMembershipsToPermissions(requiredPerm, memberships, authConfig)
|
||||
return requestedPermissions, allPermissions, nil
|
||||
}
|
||||
|
||||
func mapGrantToPermissions(requiredPerm string, grant *Grant, authConfig Config) (requestPermissions, allPermissions []string) {
|
||||
func mapMembershipsToPermissions(requiredPerm string, memberships []*Membership, authConfig Config) (requestPermissions, allPermissions []string) {
|
||||
requestPermissions = make([]string, 0)
|
||||
allPermissions = make([]string, 0)
|
||||
for _, role := range grant.Roles {
|
||||
requestPermissions, allPermissions = mapRoleToPerm(requiredPerm, role, authConfig, requestPermissions, allPermissions)
|
||||
for _, membership := range memberships {
|
||||
requestPermissions, allPermissions = mapMembershipToPerm(requiredPerm, membership, authConfig, requestPermissions, allPermissions)
|
||||
}
|
||||
|
||||
return requestPermissions, allPermissions
|
||||
}
|
||||
|
||||
func mapRoleToPerm(requiredPerm, actualRole string, authConfig Config, requestPermissions, allPermissions []string) ([]string, []string) {
|
||||
roleName, roleContextID := SplitPermission(actualRole)
|
||||
perms := authConfig.getPermissionsFromRole(roleName)
|
||||
func mapMembershipToPerm(requiredPerm string, membership *Membership, authConfig Config, requestPermissions, allPermissions []string) ([]string, []string) {
|
||||
roleNames, roleContextID := roleWithContext(membership)
|
||||
for _, roleName := range roleNames {
|
||||
perms := authConfig.getPermissionsFromRole(roleName)
|
||||
|
||||
for _, p := range perms {
|
||||
permWithCtx := addRoleContextIDToPerm(p, roleContextID)
|
||||
if !ExistsPerm(allPermissions, permWithCtx) {
|
||||
allPermissions = append(allPermissions, permWithCtx)
|
||||
}
|
||||
for _, p := range perms {
|
||||
permWithCtx := addRoleContextIDToPerm(p, roleContextID)
|
||||
if !ExistsPerm(allPermissions, permWithCtx) {
|
||||
allPermissions = append(allPermissions, permWithCtx)
|
||||
}
|
||||
|
||||
p, _ = SplitPermission(p)
|
||||
if p == requiredPerm {
|
||||
if !ExistsPerm(requestPermissions, permWithCtx) {
|
||||
requestPermissions = append(requestPermissions, permWithCtx)
|
||||
p, _ = SplitPermission(p)
|
||||
if p == requiredPerm {
|
||||
if !ExistsPerm(requestPermissions, permWithCtx) {
|
||||
requestPermissions = append(requestPermissions, permWithCtx)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -72,3 +73,10 @@ func ExistsPerm(existingPermissions []string, perm string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func roleWithContext(membership *Membership) (roles []string, ctxID string) {
|
||||
if membership.MemberType == MemberTypeProject || membership.MemberType == MemberTypeProjectGrant {
|
||||
return membership.Roles, membership.ObjectID
|
||||
}
|
||||
return membership.Roles, ""
|
||||
}
|
||||
|
@ -12,15 +12,14 @@ func getTestCtx(userID, orgID string) context.Context {
|
||||
}
|
||||
|
||||
type testVerifier struct {
|
||||
grant *Grant
|
||||
memberships []*Membership
|
||||
}
|
||||
|
||||
func (v *testVerifier) VerifyAccessToken(ctx context.Context, token, clientID string) (string, string, string, string, error) {
|
||||
return "userID", "agentID", "de", "orgID", nil
|
||||
}
|
||||
|
||||
func (v *testVerifier) ResolveGrants(ctx context.Context) (*Grant, error) {
|
||||
return v.grant, nil
|
||||
func (v *testVerifier) SearchMyMemberships(ctx context.Context) ([]*Membership, error) {
|
||||
return v.memberships, nil
|
||||
}
|
||||
|
||||
func (v *testVerifier) ProjectIDAndOriginsByClientID(ctx context.Context, clientID string) (string, []string, error) {
|
||||
@ -65,8 +64,10 @@ func Test_GetUserMethodPermissions(t *testing.T) {
|
||||
name: "Empty Context",
|
||||
args: args{
|
||||
ctxData: CtxData{},
|
||||
verifier: Start(&testVerifier{grant: &Grant{
|
||||
Roles: []string{"ORG_OWNER"},
|
||||
verifier: Start(&testVerifier{memberships: []*Membership{
|
||||
{
|
||||
Roles: []string{"ORG_OWNER"},
|
||||
},
|
||||
}}),
|
||||
requiredPerm: "project.read",
|
||||
authConfig: Config{
|
||||
@ -90,7 +91,7 @@ func Test_GetUserMethodPermissions(t *testing.T) {
|
||||
name: "No Grants",
|
||||
args: args{
|
||||
ctxData: CtxData{},
|
||||
verifier: Start(&testVerifier{grant: &Grant{}}),
|
||||
verifier: Start(&testVerifier{memberships: []*Membership{}}),
|
||||
requiredPerm: "project.read",
|
||||
authConfig: Config{
|
||||
RolePermissionMappings: []RoleMapping{
|
||||
@ -111,8 +112,13 @@ func Test_GetUserMethodPermissions(t *testing.T) {
|
||||
name: "Get Permissions",
|
||||
args: args{
|
||||
ctxData: CtxData{UserID: "userID", OrgID: "orgID"},
|
||||
verifier: Start(&testVerifier{grant: &Grant{
|
||||
Roles: []string{"IAM_OWNER"},
|
||||
verifier: Start(&testVerifier{memberships: []*Membership{
|
||||
{
|
||||
AggregateID: "IAM",
|
||||
ObjectID: "IAM",
|
||||
MemberType: MemberTypeIam,
|
||||
Roles: []string{"IAM_OWNER"},
|
||||
},
|
||||
}}),
|
||||
requiredPerm: "project.read",
|
||||
authConfig: Config{
|
||||
@ -150,10 +156,10 @@ func Test_GetUserMethodPermissions(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func Test_MapGrantsToPermissions(t *testing.T) {
|
||||
func Test_MapMembershipToPermissions(t *testing.T) {
|
||||
type args struct {
|
||||
requiredPerm string
|
||||
grant *Grant
|
||||
membership []*Membership
|
||||
authConfig Config
|
||||
}
|
||||
tests := []struct {
|
||||
@ -166,7 +172,14 @@ func Test_MapGrantsToPermissions(t *testing.T) {
|
||||
name: "One Role existing perm",
|
||||
args: args{
|
||||
requiredPerm: "project.read",
|
||||
grant: &Grant{Roles: []string{"ORG_OWNER"}},
|
||||
membership: []*Membership{
|
||||
{
|
||||
AggregateID: "1",
|
||||
ObjectID: "1",
|
||||
MemberType: MemberTypeOrganisation,
|
||||
Roles: []string{"ORG_OWNER"},
|
||||
},
|
||||
},
|
||||
authConfig: Config{
|
||||
RolePermissionMappings: []RoleMapping{
|
||||
{
|
||||
@ -187,7 +200,14 @@ func Test_MapGrantsToPermissions(t *testing.T) {
|
||||
name: "One Role not existing perm",
|
||||
args: args{
|
||||
requiredPerm: "project.write",
|
||||
grant: &Grant{Roles: []string{"ORG_OWNER"}},
|
||||
membership: []*Membership{
|
||||
{
|
||||
AggregateID: "1",
|
||||
ObjectID: "1",
|
||||
MemberType: MemberTypeOrganisation,
|
||||
Roles: []string{"ORG_OWNER"},
|
||||
},
|
||||
},
|
||||
authConfig: Config{
|
||||
RolePermissionMappings: []RoleMapping{
|
||||
{
|
||||
@ -208,7 +228,20 @@ func Test_MapGrantsToPermissions(t *testing.T) {
|
||||
name: "Multiple Roles one existing",
|
||||
args: args{
|
||||
requiredPerm: "project.read",
|
||||
grant: &Grant{Roles: []string{"ORG_OWNER", "IAM_OWNER"}},
|
||||
membership: []*Membership{
|
||||
{
|
||||
AggregateID: "1",
|
||||
ObjectID: "1",
|
||||
MemberType: MemberTypeOrganisation,
|
||||
Roles: []string{"ORG_OWNER"},
|
||||
},
|
||||
{
|
||||
AggregateID: "IAM",
|
||||
ObjectID: "IAM",
|
||||
MemberType: MemberTypeIam,
|
||||
Roles: []string{"IAM_OWNER"},
|
||||
},
|
||||
},
|
||||
authConfig: Config{
|
||||
RolePermissionMappings: []RoleMapping{
|
||||
{
|
||||
@ -229,7 +262,20 @@ func Test_MapGrantsToPermissions(t *testing.T) {
|
||||
name: "Multiple Roles, global and specific",
|
||||
args: args{
|
||||
requiredPerm: "project.read",
|
||||
grant: &Grant{Roles: []string{"ORG_OWNER", "PROJECT_OWNER:1"}},
|
||||
membership: []*Membership{
|
||||
{
|
||||
AggregateID: "2",
|
||||
ObjectID: "2",
|
||||
MemberType: MemberTypeOrganisation,
|
||||
Roles: []string{"ORG_OWNER"},
|
||||
},
|
||||
{
|
||||
AggregateID: "1",
|
||||
ObjectID: "1",
|
||||
MemberType: MemberTypeProject,
|
||||
Roles: []string{"PROJECT_OWNER"},
|
||||
},
|
||||
},
|
||||
authConfig: Config{
|
||||
RolePermissionMappings: []RoleMapping{
|
||||
{
|
||||
@ -249,7 +295,7 @@ func Test_MapGrantsToPermissions(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
requestPerms, allPerms := mapGrantToPermissions(tt.args.requiredPerm, tt.args.grant, tt.args.authConfig)
|
||||
requestPerms, allPerms := mapMembershipsToPermissions(tt.args.requiredPerm, tt.args.membership, tt.args.authConfig)
|
||||
if !equalStringArray(requestPerms, tt.requestPerms) {
|
||||
t.Errorf("got wrong requestPerms, expecting: %v, actual: %v ", tt.requestPerms, requestPerms)
|
||||
}
|
||||
@ -260,10 +306,10 @@ func Test_MapGrantsToPermissions(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func Test_MapRoleToPerm(t *testing.T) {
|
||||
func Test_MapMembershipToPerm(t *testing.T) {
|
||||
type args struct {
|
||||
requiredPerm string
|
||||
actualRole string
|
||||
membership *Membership
|
||||
authConfig Config
|
||||
requestPerms []string
|
||||
allPerms []string
|
||||
@ -278,7 +324,12 @@ func Test_MapRoleToPerm(t *testing.T) {
|
||||
name: "first perm without context id",
|
||||
args: args{
|
||||
requiredPerm: "project.read",
|
||||
actualRole: "ORG_OWNER",
|
||||
membership: &Membership{
|
||||
AggregateID: "Org",
|
||||
ObjectID: "Org",
|
||||
MemberType: MemberTypeOrganisation,
|
||||
Roles: []string{"ORG_OWNER"},
|
||||
},
|
||||
authConfig: Config{
|
||||
RolePermissionMappings: []RoleMapping{
|
||||
{
|
||||
@ -301,7 +352,12 @@ func Test_MapRoleToPerm(t *testing.T) {
|
||||
name: "existing perm without context id",
|
||||
args: args{
|
||||
requiredPerm: "project.read",
|
||||
actualRole: "ORG_OWNER",
|
||||
membership: &Membership{
|
||||
AggregateID: "Org",
|
||||
ObjectID: "Org",
|
||||
MemberType: MemberTypeOrganisation,
|
||||
Roles: []string{"ORG_OWNER"},
|
||||
},
|
||||
authConfig: Config{
|
||||
RolePermissionMappings: []RoleMapping{
|
||||
{
|
||||
@ -324,7 +380,12 @@ func Test_MapRoleToPerm(t *testing.T) {
|
||||
name: "first perm with context id",
|
||||
args: args{
|
||||
requiredPerm: "project.read",
|
||||
actualRole: "PROJECT_OWNER:1",
|
||||
membership: &Membership{
|
||||
AggregateID: "1",
|
||||
ObjectID: "1",
|
||||
MemberType: MemberTypeProject,
|
||||
Roles: []string{"PROJECT_OWNER"},
|
||||
},
|
||||
authConfig: Config{
|
||||
RolePermissionMappings: []RoleMapping{
|
||||
{
|
||||
@ -347,7 +408,12 @@ func Test_MapRoleToPerm(t *testing.T) {
|
||||
name: "perm with context id, existing global",
|
||||
args: args{
|
||||
requiredPerm: "project.read",
|
||||
actualRole: "PROJECT_OWNER:1",
|
||||
membership: &Membership{
|
||||
AggregateID: "1",
|
||||
ObjectID: "1",
|
||||
MemberType: MemberTypeProject,
|
||||
Roles: []string{"PROJECT_OWNER"},
|
||||
},
|
||||
authConfig: Config{
|
||||
RolePermissionMappings: []RoleMapping{
|
||||
{
|
||||
@ -369,7 +435,7 @@ func Test_MapRoleToPerm(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
requestPerms, allPerms := mapRoleToPerm(tt.args.requiredPerm, tt.args.actualRole, tt.args.authConfig, tt.args.requestPerms, tt.args.allPerms)
|
||||
requestPerms, allPerms := mapMembershipToPerm(tt.args.requiredPerm, tt.args.membership, tt.args.authConfig, tt.args.requestPerms, tt.args.allPerms)
|
||||
if !equalStringArray(requestPerms, tt.requestPerms) {
|
||||
t.Errorf("got wrong requestPerms, expecting: %v, actual: %v ", tt.requestPerms, requestPerms)
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ type TokenVerifier struct {
|
||||
type authZRepo interface {
|
||||
VerifyAccessToken(ctx context.Context, token, clientID string) (userID, agentID, prefLang, resourceOwner string, err error)
|
||||
VerifierClientID(ctx context.Context, name string) (clientID string, err error)
|
||||
ResolveGrants(ctx context.Context) (grant *Grant, err error)
|
||||
SearchMyMemberships(ctx context.Context) ([]*Membership, error)
|
||||
ProjectIDAndOriginsByClientID(ctx context.Context, clientID string) (projectID string, origins []string, err error)
|
||||
ExistsOrg(ctx context.Context, orgID string) error
|
||||
}
|
||||
@ -86,11 +86,10 @@ func (v *TokenVerifier) clientIDFromMethod(ctx context.Context, method string) (
|
||||
v.clients.Store(prefix, c)
|
||||
return c.id, nil
|
||||
}
|
||||
|
||||
func (v *TokenVerifier) ResolveGrant(ctx context.Context) (_ *Grant, err error) {
|
||||
func (v *TokenVerifier) SearchMyMemberships(ctx context.Context) (_ []*Membership, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
return v.authZRepo.ResolveGrants(ctx)
|
||||
return v.authZRepo.SearchMyMemberships(ctx)
|
||||
}
|
||||
|
||||
func (v *TokenVerifier) ProjectIDAndOriginsByClientID(ctx context.Context, clientID string) (_ string, _ []string, err error) {
|
||||
|
@ -43,7 +43,7 @@ func Test_VerifyAccessToken(t *testing.T) {
|
||||
ctx: context.Background(),
|
||||
token: "Bearer AUTH",
|
||||
verifier: &TokenVerifier{
|
||||
authZRepo: &testVerifier{grant: &Grant{}},
|
||||
authZRepo: &testVerifier{memberships: []*Membership{}},
|
||||
clients: func() sync.Map {
|
||||
m := sync.Map{}
|
||||
m.Store("service", &client{name: "name"})
|
||||
|
@ -229,3 +229,13 @@ func (s *Server) GetMyUserChanges(ctx context.Context, request *auth.ChangesRequ
|
||||
}
|
||||
return userChangesToResponse(changes, request.GetSequenceOffset(), request.GetLimit()), nil
|
||||
}
|
||||
|
||||
func (s *Server) SearchMyUserMemberships(ctx context.Context, in *auth.UserMembershipSearchRequest) (*auth.UserMembershipSearchResponse, error) {
|
||||
request := userMembershipSearchRequestsToModel(in)
|
||||
request.AppendUserIDQuery(authz.GetCtxData(ctx).UserID)
|
||||
response, err := s.repo.SearchMyUserMemberships(ctx, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return userMembershipSearchResponseFromModel(response), nil
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package auth
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
"golang.org/x/text/language"
|
||||
@ -462,3 +461,93 @@ func ctxToObjectRoot(ctx context.Context) models.ObjectRoot {
|
||||
ResourceOwner: ctxData.ResourceOwner,
|
||||
}
|
||||
}
|
||||
|
||||
func userMembershipSearchResponseFromModel(response *usr_model.UserMembershipSearchResponse) *auth.UserMembershipSearchResponse {
|
||||
timestamp, err := ptypes.TimestampProto(response.Timestamp)
|
||||
logging.Log("GRPC-Hs8jd").OnError(err).Debug("unable to parse timestamp")
|
||||
return &auth.UserMembershipSearchResponse{
|
||||
Offset: response.Offset,
|
||||
Limit: response.Limit,
|
||||
TotalResult: response.TotalResult,
|
||||
Result: userMembershipViewsFromModel(response.Result),
|
||||
ProcessedSequence: response.Sequence,
|
||||
ViewTimestamp: timestamp,
|
||||
}
|
||||
}
|
||||
|
||||
func userMembershipViewsFromModel(memberships []*usr_model.UserMembershipView) []*auth.UserMembershipView {
|
||||
converted := make([]*auth.UserMembershipView, len(memberships))
|
||||
for i, membership := range memberships {
|
||||
converted[i] = userMembershipViewFromModel(membership)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func userMembershipViewFromModel(membership *usr_model.UserMembershipView) *auth.UserMembershipView {
|
||||
creationDate, err := ptypes.TimestampProto(membership.CreationDate)
|
||||
logging.Log("GRPC-Msnu8").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(membership.ChangeDate)
|
||||
logging.Log("GRPC-Slco9").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &auth.UserMembershipView{
|
||||
UserId: membership.UserID,
|
||||
AggregateId: membership.AggregateID,
|
||||
ObjectId: membership.ObjectID,
|
||||
MemberType: memberTypeFromModel(membership.MemberType),
|
||||
DisplayName: membership.DisplayName,
|
||||
Roles: membership.Roles,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: membership.Sequence,
|
||||
ResourceOwner: membership.ResourceOwner,
|
||||
}
|
||||
}
|
||||
|
||||
func userMembershipSearchRequestsToModel(request *auth.UserMembershipSearchRequest) *usr_model.UserMembershipSearchRequest {
|
||||
return &usr_model.UserMembershipSearchRequest{
|
||||
Offset: request.Offset,
|
||||
Limit: request.Limit,
|
||||
Queries: userMembershipSearchQueriesToModel(request.Queries),
|
||||
}
|
||||
}
|
||||
|
||||
func userMembershipSearchQueriesToModel(queries []*auth.UserMembershipSearchQuery) []*usr_model.UserMembershipSearchQuery {
|
||||
converted := make([]*usr_model.UserMembershipSearchQuery, len(queries))
|
||||
for i, q := range queries {
|
||||
converted[i] = userMembershipSearchQueryToModel(q)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func userMembershipSearchQueryToModel(query *auth.UserMembershipSearchQuery) *usr_model.UserMembershipSearchQuery {
|
||||
return &usr_model.UserMembershipSearchQuery{
|
||||
Key: userMembershipSearchKeyToModel(query.Key),
|
||||
Method: searchMethodToModel(query.Method),
|
||||
Value: query.Value,
|
||||
}
|
||||
}
|
||||
|
||||
func userMembershipSearchKeyToModel(key auth.UserMembershipSearchKey) usr_model.UserMembershipSearchKey {
|
||||
switch key {
|
||||
case auth.UserMembershipSearchKey_USERMEMBERSHIPSEARCHKEY_TYPE:
|
||||
return usr_model.UserMembershipSearchKeyMemberType
|
||||
case auth.UserMembershipSearchKey_USERMEMBERSHIPSEARCHKEY_OBJECT_ID:
|
||||
return usr_model.UserMembershipSearchKeyObjectID
|
||||
default:
|
||||
return usr_model.UserMembershipSearchKeyUnspecified
|
||||
}
|
||||
}
|
||||
|
||||
func memberTypeFromModel(memberType usr_model.MemberType) auth.MemberType {
|
||||
switch memberType {
|
||||
case usr_model.MemberTypeOrganisation:
|
||||
return auth.MemberType_MEMBERTYPE_ORGANISATION
|
||||
case usr_model.MemberTypeProject:
|
||||
return auth.MemberType_MEMBERTYPE_PROJECT
|
||||
case usr_model.MemberTypeProjectGrant:
|
||||
return auth.MemberType_MEMBERTYPE_PROJECT_GRANT
|
||||
default:
|
||||
return auth.MemberType_MEMBERTYPE_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package auth
|
||||
import (
|
||||
"github.com/caos/logging"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
auth "github.com/caos/zitadel/pkg/grpc/auth"
|
||||
"github.com/caos/zitadel/pkg/grpc/auth"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
)
|
||||
|
||||
|
@ -2,9 +2,10 @@ package auth
|
||||
|
||||
import (
|
||||
"github.com/caos/logging"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/caos/zitadel/pkg/grpc/auth"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
)
|
||||
|
||||
func machineViewFromModel(machine *usr_model.MachineView) *auth.MachineView {
|
||||
@ -16,36 +17,3 @@ func machineViewFromModel(machine *usr_model.MachineView) *auth.MachineView {
|
||||
LastKeyAdded: lastKeyAdded,
|
||||
}
|
||||
}
|
||||
|
||||
func machineKeyViewsFromModel(keys ...*usr_model.MachineKeyView) []*auth.MachineKeyView {
|
||||
keyViews := make([]*auth.MachineKeyView, len(keys))
|
||||
for i, key := range keys {
|
||||
keyViews[i] = machineKeyViewFromModel(key)
|
||||
}
|
||||
return keyViews
|
||||
}
|
||||
|
||||
func machineKeyViewFromModel(key *usr_model.MachineKeyView) *auth.MachineKeyView {
|
||||
creationDate, err := ptypes.TimestampProto(key.CreationDate)
|
||||
logging.Log("MANAG-gluk7").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
expirationDate, err := ptypes.TimestampProto(key.CreationDate)
|
||||
logging.Log("MANAG-gluk7").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &auth.MachineKeyView{
|
||||
Id: key.ID,
|
||||
CreationDate: creationDate,
|
||||
ExpirationDate: expirationDate,
|
||||
Sequence: key.Sequence,
|
||||
Type: machineKeyTypeFromModel(key.Type),
|
||||
}
|
||||
}
|
||||
|
||||
func machineKeyTypeFromModel(typ usr_model.MachineKeyType) auth.MachineKeyType {
|
||||
switch typ {
|
||||
case usr_model.MachineKeyTypeJSON:
|
||||
return auth.MachineKeyType_MACHINEKEY_JSON
|
||||
default:
|
||||
return auth.MachineKeyType_MACHINEKEY_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,13 @@ func (s *Server) CreateOIDCApplication(ctx context.Context, in *management.OIDCA
|
||||
}
|
||||
return oidcAppFromDomain(app), nil
|
||||
}
|
||||
func (s *Server) CreateAPIApplication(ctx context.Context, in *management.APIApplicationCreate) (*management.Application, error) {
|
||||
app, err := s.project.AddApplication(ctx, apiAppCreateToModel(in))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return appFromModel(app), nil
|
||||
}
|
||||
func (s *Server) UpdateApplication(ctx context.Context, in *management.ApplicationUpdate) (*management.Application, error) {
|
||||
app, err := s.command.ChangeApplication(ctx, in.ProjectId, appUpdateToDomain(in), authz.GetCtxData(ctx).OrgID)
|
||||
if err != nil {
|
||||
@ -61,6 +68,14 @@ func (s *Server) UpdateApplicationOIDCConfig(ctx context.Context, in *management
|
||||
return oidcConfigFromDomain(config), nil
|
||||
}
|
||||
|
||||
func (s *Server) UpdateApplicationAPIConfig(ctx context.Context, in *management.APIConfigUpdate) (*management.APIConfig, error) {
|
||||
config, err := s.project.ChangeAPIConfig(ctx, apiConfigUpdateToModel(in))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return apiConfigFromModel(config), nil
|
||||
}
|
||||
|
||||
func (s *Server) RegenerateOIDCClientSecret(ctx context.Context, in *management.ApplicationID) (*management.ClientSecret, error) {
|
||||
config, err := s.command.ChangeOIDCApplicationSecret(ctx, in.ProjectId, in.Id, authz.GetCtxData(ctx).ResourceOwner)
|
||||
if err != nil {
|
||||
@ -69,6 +84,14 @@ func (s *Server) RegenerateOIDCClientSecret(ctx context.Context, in *management.
|
||||
return &management.ClientSecret{ClientSecret: config.ClientSecretString}, nil
|
||||
}
|
||||
|
||||
func (s *Server) RegenerateAPIClientSecret(ctx context.Context, in *management.ApplicationID) (*management.ClientSecret, error) {
|
||||
config, err := s.project.ChangeAPIConfigSecret(ctx, in.ProjectId, in.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &management.ClientSecret{ClientSecret: config.ClientSecretString}, nil
|
||||
}
|
||||
|
||||
func (s *Server) ApplicationChanges(ctx context.Context, changesRequest *management.ChangeRequest) (*management.Changes, error) {
|
||||
response, err := s.project.ApplicationChanges(ctx, changesRequest.Id, changesRequest.SecId, changesRequest.SequenceOffset, changesRequest.Limit, changesRequest.Asc)
|
||||
if err != nil {
|
||||
@ -76,3 +99,32 @@ func (s *Server) ApplicationChanges(ctx context.Context, changesRequest *managem
|
||||
}
|
||||
return appChangesToResponse(response, changesRequest.GetSequenceOffset(), changesRequest.GetLimit()), nil
|
||||
}
|
||||
|
||||
func (s *Server) SearchClientKeys(ctx context.Context, req *management.ClientKeySearchRequest) (*management.ClientKeySearchResponse, error) {
|
||||
result, err := s.project.SearchClientKeys(ctx, clientKeySearchRequestToModel(req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return clientKeySearchResponseFromModel(result), nil
|
||||
}
|
||||
|
||||
func (s *Server) GetClientKey(ctx context.Context, req *management.ClientKeyIDRequest) (*management.ClientKeyView, error) {
|
||||
key, err := s.project.GetClientKey(ctx, req.ProjectId, req.ApplicationId, req.KeyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return clientKeyViewFromModel(key), nil
|
||||
}
|
||||
|
||||
func (s *Server) AddClientKey(ctx context.Context, req *management.AddClientKeyRequest) (*management.AddClientKeyResponse, error) {
|
||||
key, err := s.project.AddClientKey(ctx, addClientKeyToModel(req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return addClientKeyFromModel(key), nil
|
||||
}
|
||||
|
||||
func (s *Server) DeleteClientKey(ctx context.Context, req *management.ClientKeyIDRequest) (*empty.Empty, error) {
|
||||
err := s.project.RemoveClientKey(ctx, req.ProjectId, req.ApplicationId, req.KeyId)
|
||||
return &empty.Empty{}, err
|
||||
}
|
||||
|
@ -2,18 +2,20 @@ package management
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
"time"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
key_model "github.com/caos/zitadel/internal/key/model"
|
||||
"github.com/caos/zitadel/internal/model"
|
||||
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/caos/zitadel/pkg/grpc/management"
|
||||
"github.com/caos/zitadel/pkg/grpc/message"
|
||||
)
|
||||
@ -25,6 +27,28 @@ func appFromDomain(app domain.Application) *management.Application {
|
||||
Name: app.GetApplicationName(),
|
||||
}
|
||||
}
|
||||
func appFromModel(app *proj_model.Application) *management.Application {
|
||||
changeDate, err := ptypes.TimestampProto(app.ChangeDate)
|
||||
logging.Log("GRPC-di7rw").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &management.Application{
|
||||
Id: app.AppID,
|
||||
State: appStateFromModel(app.State),
|
||||
ChangeDate: changeDate,
|
||||
Name: app.Name,
|
||||
Sequence: app.Sequence,
|
||||
AppConfig: appConfigFromModel(app),
|
||||
}
|
||||
}
|
||||
|
||||
func appConfigFromModel(app *proj_model.Application) management.AppConfig {
|
||||
if app.Type == proj_model.AppTypeAPI {
|
||||
return &management.Application_ApiConfig{
|
||||
ApiConfig: apiConfigFromModel(app.APIConfig),
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func oidcAppFromDomain(app *domain.OIDCApp) *management.Application {
|
||||
return &management.Application{
|
||||
@ -41,6 +65,7 @@ func oidcAppConfigFromDomain(app *domain.OIDCApp) management.AppConfig {
|
||||
return &management.Application_OidcConfig{
|
||||
OidcConfig: oidcConfigFromDomain(app),
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func oidcConfigFromDomain(config *domain.OIDCApp) *management.OIDCConfig {
|
||||
@ -65,6 +90,14 @@ func oidcConfigFromDomain(config *domain.OIDCApp) *management.OIDCConfig {
|
||||
}
|
||||
}
|
||||
|
||||
func apiConfigFromModel(config *proj_model.APIConfig) *management.APIConfig {
|
||||
return &management.APIConfig{
|
||||
ClientId: config.ClientID,
|
||||
ClientSecret: config.ClientSecretString,
|
||||
AuthMethodType: apiAuthMethodTypeFromModel(config.AuthMethodType),
|
||||
}
|
||||
}
|
||||
|
||||
func oidcConfigFromApplicationViewModel(app *proj_model.ApplicationView) *management.OIDCConfig {
|
||||
return &management.OIDCConfig{
|
||||
RedirectUris: app.OIDCRedirectUris,
|
||||
@ -74,11 +107,11 @@ func oidcConfigFromApplicationViewModel(app *proj_model.ApplicationView) *manage
|
||||
ClientId: app.OIDCClientID,
|
||||
AuthMethodType: oidcAuthMethodTypeFromModel(app.OIDCAuthMethodType),
|
||||
PostLogoutRedirectUris: app.OIDCPostLogoutRedirectUris,
|
||||
Version: oidcVersionFromModel(app.OIDCVersion),
|
||||
Version: oidcVersionFromDomain(domain.OIDCVersion(app.OIDCVersion)),
|
||||
NoneCompliant: app.NoneCompliant,
|
||||
ComplianceProblems: complianceProblemsToLocalizedMessages(app.ComplianceProblems),
|
||||
DevMode: app.DevMode,
|
||||
AccessTokenType: oidcTokenTypeFromModel(app.AccessTokenType),
|
||||
AccessTokenType: oidcTokenTypeFromDomain(domain.OIDCTokenType(app.AccessTokenType)),
|
||||
AccessTokenRoleAssertion: app.AccessTokenRoleAssertion,
|
||||
IdTokenRoleAssertion: app.IDTokenRoleAssertion,
|
||||
IdTokenUserinfoAssertion: app.IDTokenUserinfoAssertion,
|
||||
@ -124,6 +157,29 @@ func appUpdateToDomain(app *management.ApplicationUpdate) domain.Application {
|
||||
}
|
||||
}
|
||||
|
||||
func apiAppCreateToModel(app *management.APIApplicationCreate) *proj_model.Application {
|
||||
return &proj_model.Application{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: app.ProjectId,
|
||||
},
|
||||
Name: app.Name,
|
||||
Type: proj_model.AppTypeAPI,
|
||||
APIConfig: &proj_model.APIConfig{
|
||||
AuthMethodType: apiAuthMethodTypeToModel(app.AuthMethodType),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func appUpdateToModel(app *management.ApplicationUpdate) *proj_model.Application {
|
||||
return &proj_model.Application{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: app.ProjectId,
|
||||
},
|
||||
AppID: app.Id,
|
||||
Name: app.Name,
|
||||
}
|
||||
}
|
||||
|
||||
func oidcConfigUpdateToDomain(app *management.OIDCConfigUpdate) *domain.OIDCApp {
|
||||
return &domain.OIDCApp{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
@ -145,6 +201,16 @@ func oidcConfigUpdateToDomain(app *management.OIDCConfigUpdate) *domain.OIDCApp
|
||||
}
|
||||
}
|
||||
|
||||
func apiConfigUpdateToModel(app *management.APIConfigUpdate) *proj_model.APIConfig {
|
||||
return &proj_model.APIConfig{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: app.ProjectId,
|
||||
},
|
||||
AppID: app.ApplicationId,
|
||||
AuthMethodType: apiAuthMethodTypeToModel(app.AuthMethodType),
|
||||
}
|
||||
}
|
||||
|
||||
func applicationSearchRequestsToModel(request *management.ApplicationSearchRequest) *proj_model.ApplicationSearchRequest {
|
||||
return &proj_model.ApplicationSearchRequest{
|
||||
Offset: request.Offset,
|
||||
@ -404,6 +470,8 @@ func oidcAuthMethodTypeToDomain(authType management.OIDCAuthMethodType) domain.O
|
||||
return domain.OIDCAuthMethodTypePost
|
||||
case management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_NONE:
|
||||
return domain.OIDCAuthMethodTypeNone
|
||||
case management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_PRIVATE_KEY_JWT:
|
||||
return domain.OIDCAuthMethodTypePrivateKeyJWT
|
||||
default:
|
||||
return domain.OIDCAuthMethodTypeBasic
|
||||
}
|
||||
@ -422,6 +490,17 @@ func oidcAuthMethodTypeFromDomain(authType domain.OIDCAuthMethodType) management
|
||||
}
|
||||
}
|
||||
|
||||
func apiAuthMethodTypeToModel(authType management.APIAuthMethodType) proj_model.APIAuthMethodType {
|
||||
switch authType {
|
||||
case management.APIAuthMethodType_APIAUTHMETHODTYPE_BASIC:
|
||||
return proj_model.APIAuthMethodTypeBasic
|
||||
case management.APIAuthMethodType_APIAUTHMETHODTYPE_PRIVATE_KEY_JWT:
|
||||
return proj_model.APIAuthMethodTypePrivateKeyJWT
|
||||
default:
|
||||
return proj_model.APIAuthMethodTypeBasic
|
||||
}
|
||||
}
|
||||
|
||||
func oidcAuthMethodTypeFromModel(authType proj_model.OIDCAuthMethodType) management.OIDCAuthMethodType {
|
||||
switch authType {
|
||||
case proj_model.OIDCAuthMethodTypeBasic:
|
||||
@ -430,6 +509,8 @@ func oidcAuthMethodTypeFromModel(authType proj_model.OIDCAuthMethodType) managem
|
||||
return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_POST
|
||||
case proj_model.OIDCAuthMethodTypeNone:
|
||||
return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_NONE
|
||||
case proj_model.OIDCAuthMethodTypePrivateKeyJWT:
|
||||
return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_PRIVATE_KEY_JWT
|
||||
default:
|
||||
return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_BASIC
|
||||
}
|
||||
@ -457,14 +538,14 @@ func oidcTokenTypeFromDomain(tokenType domain.OIDCTokenType) management.OIDCToke
|
||||
}
|
||||
}
|
||||
|
||||
func oidcTokenTypeFromModel(tokenType proj_model.OIDCTokenType) management.OIDCTokenType {
|
||||
switch tokenType {
|
||||
case proj_model.OIDCTokenTypeBearer:
|
||||
return management.OIDCTokenType_OIDCTokenType_Bearer
|
||||
case proj_model.OIDCTokenTypeJWT:
|
||||
return management.OIDCTokenType_OIDCTokenType_JWT
|
||||
func apiAuthMethodTypeFromModel(authType proj_model.APIAuthMethodType) management.APIAuthMethodType {
|
||||
switch authType {
|
||||
case proj_model.APIAuthMethodTypeBasic:
|
||||
return management.APIAuthMethodType_APIAUTHMETHODTYPE_BASIC
|
||||
case proj_model.APIAuthMethodTypePrivateKeyJWT:
|
||||
return management.APIAuthMethodType_APIAUTHMETHODTYPE_PRIVATE_KEY_JWT
|
||||
default:
|
||||
return management.OIDCTokenType_OIDCTokenType_Bearer
|
||||
return management.APIAuthMethodType_APIAUTHMETHODTYPE_BASIC
|
||||
}
|
||||
}
|
||||
|
||||
@ -477,15 +558,6 @@ func oidcVersionFromDomain(version domain.OIDCVersion) management.OIDCVersion {
|
||||
}
|
||||
}
|
||||
|
||||
func oidcVersionFromModel(version proj_model.OIDCVersion) management.OIDCVersion {
|
||||
switch version {
|
||||
case proj_model.OIDCVersionV1:
|
||||
return management.OIDCVersion_OIDCV1_0
|
||||
default:
|
||||
return management.OIDCVersion_OIDCV1_0
|
||||
}
|
||||
}
|
||||
|
||||
func appChangesToResponse(response *proj_model.ApplicationChanges, offset uint64, limit uint64) (_ *management.Changes) {
|
||||
return &management.Changes{
|
||||
Limit: limit,
|
||||
@ -515,3 +587,126 @@ func appChangesToMgtAPI(changes *proj_model.ApplicationChanges) (_ []*management
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func clientKeyViewsFromModel(keys ...*key_model.AuthNKeyView) []*management.ClientKeyView {
|
||||
keyViews := make([]*management.ClientKeyView, len(keys))
|
||||
for i, key := range keys {
|
||||
keyViews[i] = clientKeyViewFromModel(key)
|
||||
}
|
||||
return keyViews
|
||||
}
|
||||
|
||||
func clientKeyViewFromModel(key *key_model.AuthNKeyView) *management.ClientKeyView {
|
||||
creationDate, err := ptypes.TimestampProto(key.CreationDate)
|
||||
logging.Log("MANAG-DAs2t").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
expirationDate, err := ptypes.TimestampProto(key.ExpirationDate)
|
||||
logging.Log("MANAG-BDgh4").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &management.ClientKeyView{
|
||||
Id: key.ID,
|
||||
CreationDate: creationDate,
|
||||
ExpirationDate: expirationDate,
|
||||
Sequence: key.Sequence,
|
||||
Type: authNKeyTypeFromModel(key.Type),
|
||||
}
|
||||
}
|
||||
|
||||
func addClientKeyToModel(key *management.AddClientKeyRequest) *proj_model.ClientKey {
|
||||
expirationDate := time.Time{}
|
||||
if key.ExpirationDate != nil {
|
||||
var err error
|
||||
expirationDate, err = ptypes.Timestamp(key.ExpirationDate)
|
||||
logging.Log("MANAG-Dgt42").OnError(err).Debug("unable to parse expiration date")
|
||||
}
|
||||
|
||||
return &proj_model.ClientKey{
|
||||
ExpirationDate: expirationDate,
|
||||
Type: authNKeyTypeToModel(key.Type),
|
||||
ApplicationID: key.ApplicationId,
|
||||
ObjectRoot: models.ObjectRoot{AggregateID: key.ProjectId},
|
||||
}
|
||||
}
|
||||
|
||||
func addClientKeyFromModel(key *proj_model.ClientKey) *management.AddClientKeyResponse {
|
||||
creationDate, err := ptypes.TimestampProto(key.CreationDate)
|
||||
logging.Log("MANAG-FBzz4").OnError(err).Debug("unable to parse cretaion date")
|
||||
|
||||
expirationDate, err := ptypes.TimestampProto(key.ExpirationDate)
|
||||
logging.Log("MANAG-sag21").OnError(err).Debug("unable to parse cretaion date")
|
||||
|
||||
detail, err := json.Marshal(struct {
|
||||
Type string `json:"type"`
|
||||
KeyID string `json:"keyId"`
|
||||
Key string `json:"key"`
|
||||
AppID string `json:"appId"`
|
||||
ClientID string `json:"clientID"`
|
||||
}{
|
||||
Type: "application",
|
||||
KeyID: key.KeyID,
|
||||
Key: string(key.PrivateKey),
|
||||
AppID: key.ApplicationID,
|
||||
ClientID: key.ClientID,
|
||||
})
|
||||
logging.Log("MANAG-adt42").OnError(err).Warn("unable to marshall key")
|
||||
|
||||
return &management.AddClientKeyResponse{
|
||||
Id: key.KeyID,
|
||||
CreationDate: creationDate,
|
||||
ExpirationDate: expirationDate,
|
||||
Sequence: key.Sequence,
|
||||
KeyDetails: detail,
|
||||
Type: authNKeyTypeFromModel(key.Type),
|
||||
}
|
||||
}
|
||||
|
||||
func authNKeyTypeToModel(typ management.AuthNKeyType) key_model.AuthNKeyType {
|
||||
switch typ {
|
||||
case management.AuthNKeyType_AUTHNKEY_JSON:
|
||||
return key_model.AuthNKeyTypeJSON
|
||||
default:
|
||||
return key_model.AuthNKeyTypeNONE
|
||||
}
|
||||
}
|
||||
|
||||
func authNKeyTypeFromModel(typ key_model.AuthNKeyType) management.AuthNKeyType {
|
||||
switch typ {
|
||||
case key_model.AuthNKeyTypeJSON:
|
||||
return management.AuthNKeyType_AUTHNKEY_JSON
|
||||
default:
|
||||
return management.AuthNKeyType_AUTHNKEY_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
func clientKeySearchRequestToModel(req *management.ClientKeySearchRequest) *key_model.AuthNKeySearchRequest {
|
||||
return &key_model.AuthNKeySearchRequest{
|
||||
Offset: req.Offset,
|
||||
Limit: req.Limit,
|
||||
Asc: req.Asc,
|
||||
Queries: []*key_model.AuthNKeySearchQuery{
|
||||
{
|
||||
Key: key_model.AuthNKeyObjectType,
|
||||
Method: model.SearchMethodEquals,
|
||||
Value: key_model.AuthNKeyObjectTypeApplication,
|
||||
}, {
|
||||
Key: key_model.AuthNKeyObjectID,
|
||||
Method: model.SearchMethodEquals,
|
||||
Value: req.ApplicationId,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func clientKeySearchResponseFromModel(req *key_model.AuthNKeySearchResponse) *management.ClientKeySearchResponse {
|
||||
viewTimestamp, err := ptypes.TimestampProto(req.Timestamp)
|
||||
logging.Log("MANAG-Sk9ds").OnError(err).Debug("unable to parse cretaion date")
|
||||
|
||||
return &management.ClientKeySearchResponse{
|
||||
Offset: req.Offset,
|
||||
Limit: req.Limit,
|
||||
TotalResult: req.TotalResult,
|
||||
ProcessedSequence: req.Sequence,
|
||||
ViewTimestamp: viewTimestamp,
|
||||
Result: clientKeyViewsFromModel(req.Result...),
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
key_model "github.com/caos/zitadel/internal/key/model"
|
||||
"github.com/caos/zitadel/internal/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/caos/zitadel/pkg/grpc/management"
|
||||
@ -52,7 +53,7 @@ func machineViewFromModel(machine *usr_model.MachineView) *management.MachineVie
|
||||
}
|
||||
}
|
||||
|
||||
func machineKeyViewsFromModel(keys ...*usr_model.MachineKeyView) []*management.MachineKeyView {
|
||||
func authnKeyViewsFromModel(keys ...*key_model.AuthNKeyView) []*management.MachineKeyView {
|
||||
keyViews := make([]*management.MachineKeyView, len(keys))
|
||||
for i, key := range keys {
|
||||
keyViews[i] = machineKeyViewFromModel(key)
|
||||
@ -60,7 +61,7 @@ func machineKeyViewsFromModel(keys ...*usr_model.MachineKeyView) []*management.M
|
||||
return keyViews
|
||||
}
|
||||
|
||||
func machineKeyViewFromModel(key *usr_model.MachineKeyView) *management.MachineKeyView {
|
||||
func machineKeyViewFromModel(key *key_model.AuthNKeyView) *management.MachineKeyView {
|
||||
creationDate, err := ptypes.TimestampProto(key.CreationDate)
|
||||
logging.Log("MANAG-gluk7").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
@ -133,23 +134,27 @@ func machineKeyTypeFromDomain(typ domain.MachineKeyType) management.MachineKeyTy
|
||||
}
|
||||
}
|
||||
|
||||
func machineKeyTypeFromModel(typ usr_model.MachineKeyType) management.MachineKeyType {
|
||||
func machineKeyTypeFromModel(typ key_model.AuthNKeyType) management.MachineKeyType {
|
||||
switch typ {
|
||||
case usr_model.MachineKeyTypeJSON:
|
||||
case key_model.AuthNKeyTypeJSON:
|
||||
return management.MachineKeyType_MACHINEKEY_JSON
|
||||
default:
|
||||
return management.MachineKeyType_MACHINEKEY_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
func machineKeySearchRequestToModel(req *management.MachineKeySearchRequest) *usr_model.MachineKeySearchRequest {
|
||||
return &usr_model.MachineKeySearchRequest{
|
||||
func machineKeySearchRequestToModel(req *management.MachineKeySearchRequest) *key_model.AuthNKeySearchRequest {
|
||||
return &key_model.AuthNKeySearchRequest{
|
||||
Offset: req.Offset,
|
||||
Limit: req.Limit,
|
||||
Asc: req.Asc,
|
||||
Queries: []*usr_model.MachineKeySearchQuery{
|
||||
Queries: []*key_model.AuthNKeySearchQuery{
|
||||
{
|
||||
Key: usr_model.MachineKeyKeyUserID,
|
||||
Key: key_model.AuthNKeyObjectType,
|
||||
Method: model.SearchMethodEquals,
|
||||
Value: key_model.AuthNKeyObjectTypeUser,
|
||||
}, {
|
||||
Key: key_model.AuthNKeyObjectID,
|
||||
Method: model.SearchMethodEquals,
|
||||
Value: req.UserId,
|
||||
},
|
||||
@ -157,7 +162,7 @@ func machineKeySearchRequestToModel(req *management.MachineKeySearchRequest) *us
|
||||
}
|
||||
}
|
||||
|
||||
func machineKeySearchResponseFromModel(req *usr_model.MachineKeySearchResponse) *management.MachineKeySearchResponse {
|
||||
func machineKeySearchResponseFromModel(req *key_model.AuthNKeySearchResponse) *management.MachineKeySearchResponse {
|
||||
viewTimestamp, err := ptypes.TimestampProto(req.Timestamp)
|
||||
logging.Log("MANAG-Sk9ds").OnError(err).Debug("unable to parse cretaion date")
|
||||
|
||||
@ -167,6 +172,6 @@ func machineKeySearchResponseFromModel(req *usr_model.MachineKeySearchResponse)
|
||||
TotalResult: req.TotalResult,
|
||||
ProcessedSequence: req.Sequence,
|
||||
ViewTimestamp: viewTimestamp,
|
||||
Result: machineKeyViewsFromModel(req.Result...),
|
||||
Result: authnKeyViewsFromModel(req.Result...),
|
||||
}
|
||||
}
|
||||
|
@ -24,9 +24,10 @@ type verifierMock struct{}
|
||||
func (v *verifierMock) VerifyAccessToken(ctx context.Context, token, clientID string) (string, string, string, string, error) {
|
||||
return "", "", "", "", nil
|
||||
}
|
||||
func (v *verifierMock) ResolveGrants(ctx context.Context) (*authz.Grant, error) {
|
||||
func (v *verifierMock) SearchMyMemberships(ctx context.Context) ([]*authz.Membership, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (v *verifierMock) ProjectIDAndOriginsByClientID(ctx context.Context, clientID string) (string, []string, error) {
|
||||
return "", nil, nil
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/api/http"
|
||||
"github.com/caos/zitadel/internal/auth_request/model"
|
||||
authreq_model "github.com/caos/zitadel/internal/auth_request/model"
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||
@ -55,13 +56,17 @@ func (o *OPStorage) GetClientByClientID(ctx context.Context, id string) (_ op.Cl
|
||||
}
|
||||
|
||||
func (o *OPStorage) GetKeyByIDAndUserID(ctx context.Context, keyID, userID string) (_ *jose.JSONWebKey, err error) {
|
||||
return o.GetKeyByIDAndIssuer(ctx, keyID, userID)
|
||||
}
|
||||
|
||||
func (o *OPStorage) GetKeyByIDAndIssuer(ctx context.Context, keyID, issuer string) (_ *jose.JSONWebKey, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
key, err := o.repo.MachineKeyByID(ctx, keyID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if key.UserID != userID {
|
||||
if key.AuthIdentifier != issuer {
|
||||
return nil, errors.ThrowPermissionDenied(nil, "OIDC-24jm3", "key from different user")
|
||||
}
|
||||
publicKey, err := crypto.BytesToPublicKey(key.PublicKey)
|
||||
@ -75,6 +80,29 @@ func (o *OPStorage) GetKeyByIDAndUserID(ctx context.Context, keyID, userID strin
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (o *OPStorage) ValidateJWTProfileScopes(ctx context.Context, subject string, scopes oidc.Scopes) (oidc.Scopes, error) {
|
||||
user, err := o.repo.UserByID(ctx, subject)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := len(scopes) - 1; i >= 0; i-- {
|
||||
scope := scopes[i]
|
||||
if strings.HasPrefix(scope, authreq_model.OrgDomainPrimaryScope) {
|
||||
var orgID string
|
||||
org, err := o.repo.OrgByPrimaryDomain(strings.TrimPrefix(scope, authreq_model.OrgDomainPrimaryScope))
|
||||
if err == nil {
|
||||
orgID = org.ID
|
||||
}
|
||||
if orgID != user.ResourceOwner {
|
||||
scopes[i] = scopes[len(scopes)-1]
|
||||
scopes[len(scopes)-1] = ""
|
||||
scopes = scopes[:len(scopes)-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
return scopes, nil
|
||||
}
|
||||
|
||||
func (o *OPStorage) AuthorizeClientIDSecret(ctx context.Context, id string, secret string) (err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
@ -85,33 +113,32 @@ func (o *OPStorage) AuthorizeClientIDSecret(ctx context.Context, id string, secr
|
||||
return o.repo.AuthorizeOIDCApplication(ctx, id, secret)
|
||||
}
|
||||
|
||||
func (o *OPStorage) GetUserinfoFromToken(ctx context.Context, tokenID, subject, origin string) (_ oidc.UserInfo, err error) {
|
||||
func (o *OPStorage) SetUserinfoFromToken(ctx context.Context, userInfo oidc.UserInfoSetter, tokenID, subject, origin string) (err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
token, err := o.repo.TokenByID(ctx, subject, tokenID)
|
||||
if err != nil {
|
||||
return nil, errors.ThrowPermissionDenied(nil, "OIDC-Dsfb2", "token is not valid or has expired")
|
||||
return errors.ThrowPermissionDenied(nil, "OIDC-Dsfb2", "token is not valid or has expired")
|
||||
}
|
||||
if token.ApplicationID != "" {
|
||||
app, err := o.repo.ApplicationByClientID(ctx, token.ApplicationID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
if origin != "" && !http.IsOriginAllowed(app.OriginAllowList, origin) {
|
||||
return nil, errors.ThrowPermissionDenied(nil, "OIDC-da1f3", "origin is not allowed")
|
||||
return errors.ThrowPermissionDenied(nil, "OIDC-da1f3", "origin is not allowed")
|
||||
}
|
||||
}
|
||||
return o.GetUserinfoFromScopes(ctx, token.UserID, token.ApplicationID, token.Scopes)
|
||||
return o.SetUserinfoFromScopes(ctx, userInfo, token.UserID, token.ApplicationID, token.Scopes)
|
||||
}
|
||||
|
||||
func (o *OPStorage) GetUserinfoFromScopes(ctx context.Context, userID, applicationID string, scopes []string) (_ oidc.UserInfo, err error) {
|
||||
func (o *OPStorage) SetUserinfoFromScopes(ctx context.Context, userInfo oidc.UserInfoSetter, userID, applicationID string, scopes []string) (err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
user, err := o.repo.UserByID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
userInfo := oidc.NewUserInfo()
|
||||
roles := make([]string, 0)
|
||||
for _, scope := range scopes {
|
||||
switch scope {
|
||||
@ -160,17 +187,40 @@ func (o *OPStorage) GetUserinfoFromScopes(ctx context.Context, userID, applicati
|
||||
}
|
||||
|
||||
if len(roles) == 0 || applicationID == "" {
|
||||
return userInfo, nil
|
||||
return nil
|
||||
}
|
||||
projectRoles, err := o.assertRoles(ctx, userID, applicationID, roles)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
if len(projectRoles) > 0 {
|
||||
userInfo.AppendClaims(ClaimProjectRoles, projectRoles)
|
||||
}
|
||||
|
||||
return userInfo, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *OPStorage) SetIntrospectionFromToken(ctx context.Context, introspection oidc.IntrospectionResponse, tokenID, subject, clientID string) error {
|
||||
token, err := o.repo.TokenByID(ctx, subject, tokenID)
|
||||
if err != nil {
|
||||
return errors.ThrowPermissionDenied(nil, "OIDC-Dsfb2", "token is not valid or has expired")
|
||||
}
|
||||
app, err := o.repo.ApplicationByClientID(ctx, clientID)
|
||||
if err != nil {
|
||||
return errors.ThrowPermissionDenied(nil, "OIDC-Adfg5", "client not found")
|
||||
}
|
||||
for _, aud := range token.Audience {
|
||||
if aud == clientID || aud == app.ProjectID {
|
||||
err := o.SetUserinfoFromScopes(ctx, introspection, token.UserID, clientID, token.Scopes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
introspection.SetScopes(token.Scopes)
|
||||
introspection.SetClientID(token.ApplicationID)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return errors.ThrowPermissionDenied(nil, "OIDC-sdg3G", "token is not valid for this client")
|
||||
}
|
||||
|
||||
func (o *OPStorage) GetPrivateClaimsFromScopes(ctx context.Context, userID, clientID string, scopes []string) (claims map[string]interface{}, err error) {
|
||||
|
@ -1,13 +1,13 @@
|
||||
package oidc
|
||||
|
||||
import (
|
||||
authreq_model "github.com/caos/zitadel/internal/auth_request/model"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/caos/oidc/pkg/oidc"
|
||||
"github.com/caos/oidc/pkg/op"
|
||||
|
||||
authreq_model "github.com/caos/zitadel/internal/auth_request/model"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/project/model"
|
||||
)
|
||||
@ -37,7 +37,7 @@ func (c *Client) ApplicationType() op.ApplicationType {
|
||||
return op.ApplicationType(c.OIDCApplicationType)
|
||||
}
|
||||
|
||||
func (c *Client) AuthMethod() op.AuthMethod {
|
||||
func (c *Client) AuthMethod() oidc.AuthMethod {
|
||||
return authMethodToOIDC(c.OIDCAuthMethodType)
|
||||
}
|
||||
|
||||
@ -129,16 +129,18 @@ func accessTokenTypeToOIDC(tokenType model.OIDCTokenType) op.AccessTokenType {
|
||||
}
|
||||
}
|
||||
|
||||
func authMethodToOIDC(authType model.OIDCAuthMethodType) op.AuthMethod {
|
||||
func authMethodToOIDC(authType model.OIDCAuthMethodType) oidc.AuthMethod {
|
||||
switch authType {
|
||||
case model.OIDCAuthMethodTypeBasic:
|
||||
return op.AuthMethodBasic
|
||||
return oidc.AuthMethodBasic
|
||||
case model.OIDCAuthMethodTypePost:
|
||||
return op.AuthMethodPost
|
||||
return oidc.AuthMethodPost
|
||||
case model.OIDCAuthMethodTypeNone:
|
||||
return op.AuthMethodNone
|
||||
return oidc.AuthMethodNone
|
||||
case model.OIDCAuthMethodTypePrivateKeyJWT:
|
||||
return oidc.AuthMethodPrivateKeyJWT
|
||||
default:
|
||||
return op.AuthMethodBasic
|
||||
return oidc.AuthMethodBasic
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,9 +2,6 @@ package oidc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/telemetry/metrics"
|
||||
"github.com/caos/zitadel/internal/v2/command"
|
||||
"github.com/caos/zitadel/internal/v2/query"
|
||||
"time"
|
||||
|
||||
"github.com/caos/logging"
|
||||
@ -15,7 +12,10 @@ import (
|
||||
"github.com/caos/zitadel/internal/auth/repository"
|
||||
"github.com/caos/zitadel/internal/config/types"
|
||||
"github.com/caos/zitadel/internal/id"
|
||||
"github.com/caos/zitadel/internal/telemetry/metrics"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
"github.com/caos/zitadel/internal/v2/command"
|
||||
"github.com/caos/zitadel/internal/v2/query"
|
||||
)
|
||||
|
||||
type OPHandlerConfig struct {
|
||||
@ -34,11 +34,12 @@ type StorageConfig struct {
|
||||
}
|
||||
|
||||
type EndpointConfig struct {
|
||||
Auth *Endpoint
|
||||
Token *Endpoint
|
||||
Userinfo *Endpoint
|
||||
EndSession *Endpoint
|
||||
Keys *Endpoint
|
||||
Auth *Endpoint
|
||||
Token *Endpoint
|
||||
Introspection *Endpoint
|
||||
Userinfo *Endpoint
|
||||
EndSession *Endpoint
|
||||
Keys *Endpoint
|
||||
}
|
||||
|
||||
type Endpoint struct {
|
||||
@ -74,6 +75,7 @@ func NewProvider(ctx context.Context, config OPHandlerConfig, command *command.C
|
||||
),
|
||||
op.WithCustomAuthEndpoint(op.NewEndpointWithURL(config.Endpoints.Auth.Path, config.Endpoints.Auth.URL)),
|
||||
op.WithCustomTokenEndpoint(op.NewEndpointWithURL(config.Endpoints.Token.Path, config.Endpoints.Token.URL)),
|
||||
op.WithCustomIntrospectionEndpoint(op.NewEndpointWithURL(config.Endpoints.Introspection.Path, config.Endpoints.Introspection.URL)),
|
||||
op.WithCustomUserinfoEndpoint(op.NewEndpointWithURL(config.Endpoints.Userinfo.Path, config.Endpoints.Userinfo.URL)),
|
||||
op.WithCustomEndSessionEndpoint(op.NewEndpointWithURL(config.Endpoints.EndSession.Path, config.Endpoints.EndSession.URL)),
|
||||
op.WithCustomKeysEndpoint(op.NewEndpointWithURL(config.Endpoints.Keys.Path, config.Endpoints.Keys.URL)),
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
@ -52,6 +53,14 @@ func (repo *OrgRepository) SearchOrgs(ctx context.Context, request *org_model.Or
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) OrgByPrimaryDomain(primaryDomain string) (*org_model.OrgView, error) {
|
||||
org, err := repo.View.OrgByPrimaryDomain(primaryDomain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return model.OrgToModel(org), nil
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) GetDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicyView, error) {
|
||||
orgPolicy, err := repo.View.OrgIAMPolicyByAggregateID(repo.SystemDefaults.IamID)
|
||||
if err != nil {
|
||||
|
@ -2,20 +2,23 @@ package eventstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/auth/repository/eventsourcing/view"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
user_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
"time"
|
||||
|
||||
"github.com/caos/zitadel/internal/auth/repository/eventsourcing/view"
|
||||
)
|
||||
|
||||
type TokenRepo struct {
|
||||
UserEvents *user_event.UserEventstore
|
||||
View *view.View
|
||||
UserEvents *user_event.UserEventstore
|
||||
ProjectEvents *proj_event.ProjectEventstore
|
||||
View *view.View
|
||||
}
|
||||
|
||||
func (repo *TokenRepo) IsTokenValid(ctx context.Context, userID, tokenID string) (bool, error) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user