From db11cf1da3deafb7ff7d074847de2e56a7013dbd Mon Sep 17 00:00:00 2001 From: Fabi <38692350+fgerschwiler@users.noreply.github.com> Date: Mon, 8 Feb 2021 16:48:41 +0100 Subject: [PATCH] feat: Merge master (#1260) * 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] 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] 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] 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] 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] 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] 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] 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] 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] 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] 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] 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] 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] 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] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Max Peintner * 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] 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] 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] 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] 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] 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] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Max Peintner 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] 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] 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] 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] 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] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Max Peintner * 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] 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] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Max Peintner * 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] 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] 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] 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] 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] 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] 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] 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] 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] 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] 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] 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 Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Maximilian Peintner Co-authored-by: Livio Amstutz * 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] 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] 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] 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] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Max Peintner * 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 * 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 Co-authored-by: Elio Bischof * Merge branch 'new-eventstore' into cascades # Conflicts: # internal/auth/repository/auth_request.go # internal/auth/repository/eventsourcing/eventstore/auth_request.go # internal/management/repository/eventsourcing/eventstore/user_grant.go # internal/management/repository/user_grant.go # internal/ui/login/handler/external_login_handler.go # internal/ui/login/handler/external_register_handler.go # internal/ui/login/handler/init_password_handler.go # internal/ui/login/handler/register_handler.go # internal/user/repository/view/model/notify_user.go # internal/v2/command/org_policy_login.go # internal/v2/command/project.go # internal/v2/command/user.go # internal/v2/command/user_human.go # internal/v2/command/user_human_externalidp.go # internal/v2/command/user_human_init.go # internal/v2/command/user_human_password.go # internal/v2/command/user_human_webauthn.go # internal/v2/domain/next_step.go # internal/v2/domain/policy_login.go # internal/v2/domain/request.go * chore: add local migrate_local.go again (#1261) Co-authored-by: Max Peintner 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: Livio Amstutz Co-authored-by: Maximilian Peintner Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com> Co-authored-by: Florian Forster Co-authored-by: Elio Bischof --- .github/dependabot.yml | 10 +- .github/workflows/codecov.yml | 21 +- .github/workflows/operator.yml | 165 + .../workflows/{release.yml => zitadel.yml} | 8 +- .gitignore | 5 +- .releaserc.js | 17 +- build/console/package-lock.json | 3 + build/cr-backup/Dockerfile | 22 + build/cr-backup/scripts/backup-cockroach.sh | 17 + build/cr-backup/scripts/clean-db-cockroach.sh | 4 + .../scripts/clean-migration-cockroach.sh | 3 + .../cr-backup/scripts/clean-user-cockroach.sh | 4 + build/cr-backup/scripts/restore-cockroach.sh | 33 + build/docker-compose-debug.yml | 4 +- build/docker-compose-dev.yml | 4 +- build/dockerfile | 18 +- build/operator/.dockerignore | 1 + build/operator/Dockerfile | 59 + build/operator/prebuild.sh | 5 + changelog.config.js | 3 + cmd/database-debug/main.go | 50 + cmd/operator-debug/main.go | 47 + cmd/zitadel/setup.yaml | 88 +- cmd/zitadel/system-defaults.yaml | 2 +- cmd/zitadelctl/cmds/backup.go | 73 + cmd/zitadelctl/cmds/backuplist.go | 54 + cmd/zitadelctl/cmds/readsecret.go | 57 + cmd/zitadelctl/cmds/restore.go | 100 + cmd/zitadelctl/cmds/root.go | 72 + cmd/zitadelctl/cmds/start.go | 82 + cmd/zitadelctl/cmds/takeoff.go | 127 + cmd/zitadelctl/cmds/writesecret.go | 115 + cmd/zitadelctl/main.go | 31 + console/package-lock.json | 4252 +++++++++-------- console/package.json | 20 +- console/src/app/favicon-96x96.ico | Bin 0 -> 38078 bytes .../services/interceptors/auth.interceptor.ts | 42 +- .../assets/icons/android-chrome-512x512.png | Bin 61750 -> 137768 bytes console/src/favicon.ico | Bin 1150 -> 38078 bytes go.mod | 16 +- go.sum | 517 +- .../eventsourcing/eventstore/administrator.go | 2 +- .../eventsourcing/eventstore/iam.go | 129 +- .../eventsourcing/eventstore/org.go | 2 +- .../eventsourcing/handler/handler.go | 4 + .../eventsourcing/handler/iam_member.go | 6 +- .../eventsourcing/handler/idp_config.go | 6 +- .../eventsourcing/handler/idp_providers.go | 6 +- .../eventsourcing/handler/label_policy.go | 6 +- .../eventsourcing/handler/login_policy.go | 6 +- .../eventsourcing/handler/mail_template.go | 105 + .../eventsourcing/handler/mail_text.go | 109 + .../repository/eventsourcing/handler/org.go | 6 +- .../eventsourcing/handler/org_iam_policy.go | 6 +- .../handler/password_age_policy.go | 6 +- .../handler/password_complexity_policy.go | 6 +- .../handler/password_lockout_policy.go | 6 +- .../repository/eventsourcing/handler/user.go | 6 +- .../handler/user_external_idps.go | 6 +- .../eventsourcing/view/external_idps.go | 4 +- .../eventsourcing/view/iam_member.go | 4 +- .../eventsourcing/view/idp_configs.go | 4 +- .../eventsourcing/view/idp_providers.go | 4 +- .../eventsourcing/view/label_policies.go | 4 +- .../eventsourcing/view/login_policies.go | 4 +- .../eventsourcing/view/mail_templates.go | 44 + .../eventsourcing/view/mail_texts.go | 48 + .../repository/eventsourcing/view/org.go | 4 +- .../eventsourcing/view/org_iam_policy.go | 4 +- .../eventsourcing/view/password_age_policy.go | 4 +- .../view/password_complexity_policy.go | 4 +- .../view/password_lockout_policy.go | 4 +- .../repository/eventsourcing/view/sequence.go | 12 +- .../repository/eventsourcing/view/user.go | 4 +- internal/admin/repository/iam.go | 9 + internal/api/grpc/admin/template.go | 24 + internal/api/grpc/admin/template_converter.go | 42 + internal/api/grpc/admin/text.go | 32 + internal/api/grpc/admin/text_converter.go | 78 + internal/api/grpc/management/mail_template.go | 45 + .../management/mail_template_converter.go | 42 + internal/api/grpc/management/mail_text.go | 45 + .../grpc/management/mail_text_converter.go | 82 + .../api/grpc/management/project_converter.go | 3 + .../eventsourcing/eventstore/org.go | 2 +- .../eventsourcing/eventstore/user.go | 2 +- .../eventsourcing/eventstore/user_grant.go | 2 +- .../eventsourcing/handler/application.go | 2 +- .../eventsourcing/handler/idp_config.go | 6 +- .../eventsourcing/handler/idp_providers.go | 6 +- .../repository/eventsourcing/handler/key.go | 6 +- .../eventsourcing/handler/login_policy.go | 6 +- .../eventsourcing/handler/machine_keys.go | 7 +- .../repository/eventsourcing/handler/org.go | 7 +- .../eventsourcing/handler/org_iam_policy.go | 8 +- .../handler/password_complexity_policy.go | 8 +- .../eventsourcing/handler/project_role.go | 9 +- .../repository/eventsourcing/handler/token.go | 6 +- .../repository/eventsourcing/handler/user.go | 6 +- .../handler/user_external_idps.go | 6 +- .../eventsourcing/handler/user_grant.go | 6 +- .../eventsourcing/handler/user_membership.go | 6 +- .../eventsourcing/handler/user_session.go | 6 +- .../eventsourcing/view/application.go | 2 +- .../eventsourcing/view/external_idps.go | 4 +- .../eventsourcing/view/idp_configs.go | 4 +- .../eventsourcing/view/idp_providers.go | 4 +- .../auth/repository/eventsourcing/view/key.go | 4 +- .../eventsourcing/view/login_policies.go | 4 +- .../eventsourcing/view/machine_keys.go | 4 +- .../auth/repository/eventsourcing/view/org.go | 4 +- .../eventsourcing/view/org_iam_policy.go | 4 +- .../view/password_complexity_policy.go | 4 +- .../eventsourcing/view/project_role.go | 4 +- .../repository/eventsourcing/view/sequence.go | 8 +- .../repository/eventsourcing/view/token.go | 4 +- .../repository/eventsourcing/view/user.go | 4 +- .../eventsourcing/view/user_grant.go | 4 +- .../eventsourcing/view/user_membership.go | 4 +- .../eventsourcing/view/user_session.go | 4 +- .../eventsourcing/handler/application.go | 6 +- .../repository/eventsourcing/handler/org.go | 7 +- .../eventsourcing/handler/user_grant.go | 6 +- .../eventsourcing/view/application.go | 4 +- .../repository/eventsourcing/view/org.go | 4 +- .../repository/eventsourcing/view/sequence.go | 8 +- .../repository/eventsourcing/view/token.go | 4 +- .../eventsourcing/view/user_grant.go | 4 +- internal/eventstore/query/handler.go | 28 +- internal/eventstore/spooler/spooler_test.go | 2 +- internal/iam/model/iam.go | 12 + internal/iam/model/mail_template.go | 17 + internal/iam/model/mail_template_view.go | 47 + internal/iam/model/mail_text.go | 28 + internal/iam/model/mail_text_view.go | 60 + .../repository/eventsourcing/eventstore.go | 115 + .../eventsourcing/eventstore_mock_test.go | 26 + .../eventsourcing/eventstore_test.go | 318 ++ internal/iam/repository/eventsourcing/iam.go | 96 + .../iam/repository/eventsourcing/model/iam.go | 34 +- .../eventsourcing/model/mail_template.go | 64 + .../eventsourcing/model/mail_template_test.go | 126 + .../eventsourcing/model/mail_text.go | 157 + .../eventsourcing/model/mail_text_test.go | 134 + .../repository/eventsourcing/model/types.go | 5 + internal/iam/repository/view/idp_view.go | 4 +- .../iam/repository/view/label_policy_view.go | 4 +- .../iam/repository/view/login_policy_view.go | 4 +- .../iam/repository/view/mail_template_view.go | 32 + .../iam/repository/view/mail_text_view.go | 54 + .../repository/view/model/mail_template.go | 80 + .../view/model/mail_template_query.go | 59 + .../iam/repository/view/model/mail_text.go | 117 + .../repository/view/model/mail_text_query.go | 63 + .../repository/view/org_iam_policy_view.go | 4 +- .../view/password_age_policy_view.go | 4 +- .../view/password_complexity_policy_view.go | 4 +- .../view/password_lockout_policy_view.go | 4 +- .../eventsourcing/eventstore/org.go | 88 +- .../eventsourcing/eventstore/project.go | 14 +- .../eventsourcing/eventstore/user.go | 8 +- .../eventsourcing/eventstore/user_grant.go | 2 +- .../eventsourcing/handler/application.go | 6 +- .../eventsourcing/handler/handler.go | 4 + .../eventsourcing/handler/idp_config.go | 8 +- .../eventsourcing/handler/idp_providers.go | 6 +- .../eventsourcing/handler/label_policy.go | 6 +- .../eventsourcing/handler/login_policy.go | 6 +- .../eventsourcing/handler/machine_keys.go | 6 +- .../eventsourcing/handler/mail_template.go | 107 + .../eventsourcing/handler/mail_text.go | 113 + .../repository/eventsourcing/handler/org.go | 8 +- .../eventsourcing/handler/org_domain.go | 6 +- .../eventsourcing/handler/org_iam_policy.go | 6 +- .../eventsourcing/handler/org_member.go | 6 +- .../handler/password_age_policy.go | 6 +- .../handler/password_complexity_policy.go | 6 +- .../handler/password_lockout_policy.go | 6 +- .../eventsourcing/handler/project.go | 6 +- .../eventsourcing/handler/project_grant.go | 6 +- .../handler/project_grant_member.go | 6 +- .../eventsourcing/handler/project_member.go | 6 +- .../eventsourcing/handler/project_role.go | 6 +- .../repository/eventsourcing/handler/user.go | 6 +- .../handler/user_external_idps.go | 8 +- .../eventsourcing/handler/user_grant.go | 8 +- .../eventsourcing/handler/user_membership.go | 8 +- .../eventsourcing/view/application.go | 4 +- .../eventsourcing/view/external_idps.go | 4 +- .../eventsourcing/view/idp_configs.go | 4 +- .../eventsourcing/view/idp_providers.go | 4 +- .../eventsourcing/view/label_policies.go | 4 +- .../eventsourcing/view/login_policies.go | 4 +- .../eventsourcing/view/machine_keys.go | 4 +- .../eventsourcing/view/mail_templates.go | 53 + .../eventsourcing/view/mail_texts.go | 57 + .../repository/eventsourcing/view/org.go | 4 +- .../eventsourcing/view/org_domain.go | 4 +- .../eventsourcing/view/org_iam_policy.go | 4 +- .../eventsourcing/view/org_member.go | 4 +- .../eventsourcing/view/password_age_policy.go | 4 +- .../view/password_complexity_policy.go | 4 +- .../view/password_lockout_policy.go | 4 +- .../repository/eventsourcing/view/project.go | 4 +- .../eventsourcing/view/project_grant.go | 4 +- .../view/project_grant_member.go | 4 +- .../eventsourcing/view/project_member.go | 4 +- .../eventsourcing/view/project_role.go | 4 +- .../repository/eventsourcing/view/sequence.go | 8 +- .../repository/eventsourcing/view/user.go | 4 +- .../eventsourcing/view/user_grant.go | 4 +- .../eventsourcing/view/user_membership.go | 4 +- internal/management/repository/org.go | 12 + .../eventsourcing/handler/notification.go | 127 +- .../eventsourcing/handler/notify_user.go | 6 +- .../eventsourcing/view/mail_template.go | 10 + .../eventsourcing/view/mail_text.go | 10 + .../eventsourcing/view/notification.go | 4 +- .../eventsourcing/view/notify_user.go | 4 +- .../repository/eventsourcing/view/sequence.go | 8 +- internal/notification/templates/template.go | 31 +- internal/notification/types/domain_claimed.go | 31 +- .../types/email_verification_code.go | 33 +- internal/notification/types/init_code.go | 32 +- internal/notification/types/password_code.go | 34 +- internal/org/model/org.go | 2 + .../repository/eventsourcing/eventstore.go | 118 + .../eventsourcing/eventstore_mock_test.go | 28 + .../eventsourcing/eventstore_test.go | 324 ++ .../eventsourcing/label_policy_test.go | 2 +- .../repository/eventsourcing/mail_template.go | 77 + .../eventsourcing/mail_template_test.go | 185 + .../org/repository/eventsourcing/mail_text.go | 94 + .../eventsourcing/mail_text_test.go | 188 + .../eventsourcing/model/mail_template.go | 31 + .../eventsourcing/model/mail_template_test.go | 83 + .../eventsourcing/model/mail_text.go | 44 + .../eventsourcing/model/mail_text_test.go | 91 + .../org/repository/eventsourcing/model/org.go | 23 + .../repository/eventsourcing/model/types.go | 7 + internal/project/model/project_role_view.go | 4 +- .../repository/view/model/project_role.go | 7 +- internal/setup/config.go | 2 + internal/setup/step10.go | 98 + .../password_complexity_policy_handler.go | 19 +- internal/ui/login/handler/renderer.go | 2 +- internal/ui/login/static/i18n/de.yaml | 12 +- internal/ui/login/static/i18n/en.yaml | 14 +- .../resources/fonts/PT_Sans/PTSans-Bold.ttf | Bin 0 -> 287936 bytes .../fonts/PT_Sans/PTSans-BoldItalic.ttf | Bin 0 -> 209784 bytes .../resources/fonts/PT_Sans/PTSans-Italic.ttf | Bin 0 -> 270524 bytes .../fonts/PT_Sans/PTSans-Regular.ttf | Bin 0 -> 278168 bytes .../resources/fonts/Raleway/Raleway-Black.ttf | Bin 0 -> 162888 bytes .../fonts/Raleway/Raleway-BlackItalic.ttf | Bin 0 -> 160968 bytes .../resources/fonts/Raleway/Raleway-Bold.ttf | Bin 0 -> 163276 bytes .../fonts/Raleway/Raleway-BoldItalic.ttf | Bin 0 -> 161484 bytes .../fonts/Raleway/Raleway-ExtraBold.ttf | Bin 0 -> 163384 bytes .../fonts/Raleway/Raleway-ExtraBoldItalic.ttf | Bin 0 -> 161576 bytes .../fonts/Raleway/Raleway-ExtraLight.ttf | Bin 0 -> 163504 bytes .../Raleway/Raleway-ExtraLightItalic.ttf | Bin 0 -> 161532 bytes .../fonts/Raleway/Raleway-Italic.ttf | Bin 0 -> 161320 bytes .../resources/fonts/Raleway/Raleway-Light.ttf | Bin 0 -> 163404 bytes .../fonts/Raleway/Raleway-LightItalic.ttf | Bin 0 -> 161564 bytes .../fonts/Raleway/Raleway-Medium.ttf | Bin 0 -> 163392 bytes .../fonts/Raleway/Raleway-MediumItalic.ttf | Bin 0 -> 161432 bytes .../fonts/Raleway/Raleway-Regular.ttf | Bin 0 -> 163388 bytes .../fonts/Raleway/Raleway-SemiBold.ttf | Bin 0 -> 163388 bytes .../fonts/Raleway/Raleway-SemiBoldItalic.ttf | Bin 0 -> 161624 bytes .../resources/fonts/Raleway/Raleway-Thin.ttf | Bin 0 -> 163208 bytes .../fonts/Raleway/Raleway-ThinItalic.ttf | Bin 0 -> 161196 bytes .../resources/fonts/Roboto/Roboto-Black.ttf | Bin 0 -> 171072 bytes .../fonts/Roboto/Roboto-BlackItalic.ttf | Bin 0 -> 177120 bytes .../resources/fonts/Roboto/Roboto-Bold.ttf | Bin 0 -> 170348 bytes .../fonts/Roboto/Roboto-BoldItalic.ttf | Bin 0 -> 174520 bytes .../resources/fonts/Roboto/Roboto-Italic.ttf | Bin 0 -> 173516 bytes .../resources/fonts/Roboto/Roboto-Light.ttf | Bin 0 -> 170012 bytes .../fonts/Roboto/Roboto-LightItalic.ttf | Bin 0 -> 176184 bytes .../resources/fonts/Roboto/Roboto-Medium.ttf | Bin 0 -> 171656 bytes .../fonts/Roboto/Roboto-MediumItalic.ttf | Bin 0 -> 176428 bytes .../resources/fonts/Roboto/Roboto-Regular.ttf | Bin 0 -> 171272 bytes .../resources/fonts/Roboto/Roboto-Thin.ttf | Bin 0 -> 171500 bytes .../fonts/Roboto/Roboto-ThinItalic.ttf | Bin 0 -> 175872 bytes .../fonts/lgn-icons/css/lgn-icon-font.css | 57 + .../fonts/lgn-icons/fonts/lgn-icons.eot | Bin 0 -> 2280 bytes .../fonts/lgn-icons/fonts/lgn-icons.svg | 20 + .../fonts/lgn-icons/fonts/lgn-icons.ttf | Bin 0 -> 2116 bytes .../fonts/lgn-icons/fonts/lgn-icons.woff | Bin 0 -> 2192 bytes .../fonts/lgn-icons/svg/angle-left-solid.svg | 1 + .../fonts/lgn-icons/svg/angle-right-solid.svg | 1 + .../fonts/lgn-icons/svg/arrow-left-solid.svg | 1 + .../fonts/lgn-icons/svg/arrow-right-solid.svg | 1 + .../fonts/lgn-icons/svg/check-solid.svg | 1 + .../lgn-icons/svg/clipboard-check-solid.svg | 1 + .../fonts/lgn-icons/svg/clipboard-solid.svg | 1 + .../svg/exclamation-circle-solid.svg | 1 + .../fonts/lgn-icons/svg/times-solid.svg | 1 + .../fonts/lgn-icons/svg/user-plus-solid.svg | 1 + .../fonts/material/MaterialIcons-Regular.eot | Bin 143258 -> 0 bytes .../fonts/material/MaterialIcons-Regular.ttf | Bin 128180 -> 0 bytes .../fonts/material/MaterialIcons-Regular.woff | Bin 57620 -> 0 bytes .../material/MaterialIcons-Regular.woff2 | Bin 44300 -> 0 bytes .../ui/login/static/resources/generate.go | 9 +- .../images/icon-newuser-dark-hover.png | Bin 1482 -> 0 bytes .../images/icon-newuser-dark-hover@2x.png | Bin 2476 -> 0 bytes .../resources/images/icon-newuser-dark.png | Bin 1494 -> 0 bytes .../resources/images/icon-newuser-dark@2x.png | Bin 2489 -> 0 bytes .../images/icon-newuser-light-hover.png | Bin 1484 -> 0 bytes .../images/icon-newuser-light-hover@2x.png | Bin 2462 -> 0 bytes .../resources/images/icon-newuser-light.png | Bin 1496 -> 0 bytes .../images/icon-newuser-light@2x.png | Bin 2494 -> 0 bytes .../resources/images/icon-user-dark-hover.png | Bin 4887 -> 0 bytes .../images/icon-user-dark-hover@2x.png | Bin 9230 -> 0 bytes .../resources/images/icon-user-dark.png | Bin 4896 -> 0 bytes .../resources/images/icon-user-dark@2x.png | Bin 9218 -> 0 bytes .../images/icon-user-light-hover.png | Bin 4322 -> 0 bytes .../images/icon-user-light-hover@2x.png | Bin 7819 -> 0 bytes .../resources/images/icon-user-light.png | Bin 4687 -> 0 bytes .../resources/images/icon-user-light@2x.png | Bin 8620 -> 0 bytes .../login/static/resources/scripts/avatar.js | 50 + .../scripts/change_password_check.js | 5 +- .../resources/scripts/copy_to_clipboard.js | 4 +- .../static/resources/scripts/form_submit.js | 17 +- .../resources/scripts/input_suffix_offset.js | 12 + .../scripts/password_policy_check.js | 37 +- .../resources/scripts/register_check.js | 3 + .../login/static/resources/scripts/theme.js | 6 + .../static/resources/scripts/webauthn.js | 2 +- .../static/resources/themes/caos/css/dark.css | 513 -- .../resources/themes/caos/css/dark.css.map | 1 - .../resources/themes/caos/css/light.css | 654 --- .../resources/themes/caos/css/light.css.map | 1 - .../static/resources/themes/caos/favicon.ico | Bin 15086 -> 0 bytes .../themes/caos/gradientdeco-full.svg | 50 - .../resources/themes/caos/logo-dark.png | Bin 32831 -> 0 bytes .../resources/themes/caos/logo-light.png | Bin 33078 -> 0 bytes .../static/resources/themes/scss/bundle.scss | 12 + .../resources/themes/scss/caos/dark.scss | 3 - .../resources/themes/scss/caos/light.scss | 4 - .../resources/themes/scss/caos/variables.scss | 27 - .../static/resources/themes/scss/light.scss | 150 - .../static/resources/themes/scss/main.scss | 498 +- .../resources/themes/scss/styles/a/a.scss | 10 + .../themes/scss/styles/a/a_theme.scss | 24 + .../account_selection/account_selection.scss | 51 + .../account_selection_theme.scss | 62 + .../themes/scss/styles/animations.scss | 22 + .../themes/scss/styles/avatar/avatar.scss | 18 + .../scss/styles/avatar/avatar_theme.scss | 66 + .../themes/scss/styles/button/button.scss | 40 + .../scss/styles/button/button_base.scss | 59 + .../scss/styles/button/button_theme.scss | 160 + .../themes/scss/styles/checkbox/checkbox.scss | 5 + .../scss/styles/checkbox/checkbox_base.scss | 54 + .../scss/styles/checkbox/checkbox_theme.scss | 55 + .../themes/scss/styles/color/all_color.scss | 19 + .../scss/styles/container/container.scss | 124 + .../styles/container/container_theme.scss | 29 + .../themes/scss/styles/core/core.scss | 33 + .../scss/styles/elevation/elevation.scss | 165 + .../themes/scss/styles/error/error.scss | 9 + .../themes/scss/styles/error/error_theme.scss | 19 + .../themes/scss/styles/footer/footer.scss | 29 + .../scss/styles/footer/footer_theme.scss | 27 + .../themes/scss/styles/header/header.scss | 16 + .../scss/styles/header/header_theme.scss | 27 + .../identity_provider/identity_provider.scss | 5 + .../identity_provider_base.scss | 42 + .../identity_provider_theme.scss | 43 + .../themes/scss/styles/input/input.scss | 23 + .../themes/scss/styles/input/input_base.scss | 32 + .../themes/scss/styles/input/input_theme.scss | 58 + .../themes/scss/styles/label/label.scss | 5 + .../themes/scss/styles/label/label_base.scss | 11 + .../themes/scss/styles/label/label_theme.scss | 25 + .../themes/scss/styles/list/list.scss | 5 + .../themes/scss/styles/list/list_base.scss | 39 + .../themes/scss/styles/list/list_theme.scss | 34 + .../styles/progress_bar/progress_bar.scss | 6 + .../progress_bar/progress_bar_base.scss | 3 + .../progress_bar/progress_bar_theme.scss | 23 + .../themes/scss/styles/qrcode/qrcode.scss | 12 + .../scss/styles/qrcode/qrcode_theme.scss | 30 + .../themes/scss/styles/radio/radio.scss | 5 + .../themes/scss/styles/radio/radio_base.scss | 111 + .../themes/scss/styles/radio/radio_theme.scss | 62 + .../themes/scss/styles/register/register.scss | 20 + .../themes/scss/styles/select/select.scss | 5 + .../scss/styles/select/select_base.scss | 14 + .../scss/styles/select/select_theme.scss | 27 + .../styles/success_label/success_label.scss | 8 + .../success_label/success_label_base.scss | 8 + .../success_label/success_label_theme.scss | 21 + .../themes/scss/styles/theming/all.scss | 41 + .../themes/scss/styles/theming/palette.scss | 265 + .../themes/scss/styles/theming/theming.scss | 217 + .../typography/faces/ailerons_font_faces.scss | 4 + .../typography/faces/lato_font_faces.scss} | 22 +- .../typography/faces/pt_sans_font_faces.scss | 26 + .../typography/faces/raleway_font_faces.scss | 113 + .../typography/faces/roboto_font_faces.scss | 76 + .../scss/styles/typography/typography.scss | 225 + .../resources/themes/scss/variables.scss | 58 - .../themes/scss/zitadel-alternative.scss | 142 + .../static/resources/themes/scss/zitadel.scss | 33 + .../resources/themes/scss/zitadel/dark.scss | 3 - .../resources/themes/scss/zitadel/light.scss | 4 - .../themes/scss/zitadel/variables.scss | 8 - .../resources/themes/zitadel/css/bundle.css | 2119 ++++++++ .../themes/zitadel/css/bundle.css.map | 1 + .../resources/themes/zitadel/css/dark.css | 513 -- .../resources/themes/zitadel/css/dark.css.map | 1 - .../resources/themes/zitadel/css/light.css | 651 --- .../themes/zitadel/css/light.css.map | 1 - .../resources/themes/zitadel/css/main.css | 22 + .../resources/themes/zitadel/css/main.css.map | 1 + .../resources/themes/zitadel/css/zitadel.css | 1913 ++++++++ .../themes/zitadel/css/zitadel.css.map | 1 + .../resources/themes/zitadel/favicon.ico | Bin 15086 -> 38078 bytes .../resources/themes/zitadel/logo-dark.png | Bin 52154 -> 0 bytes .../resources/themes/zitadel/logo-dark.svg | 12 + .../resources/themes/zitadel/logo-light.png | Bin 19825 -> 0 bytes .../resources/themes/zitadel/logo-light.svg | 8 + .../themes/zitadel/select_arrow_dark.svg | 2 + .../themes/zitadel/select_arrow_light.svg | 2 + .../static/templates/change_password.html | 41 +- .../templates/change_password_done.html | 15 +- .../static/templates/change_username.html | 22 +- .../templates/change_username_done.html | 10 +- .../login/static/templates/error-message.html | 7 +- internal/ui/login/static/templates/error.html | 13 +- .../templates/external_not_found_option.html | 21 +- .../ui/login/static/templates/footer.html | 6 +- .../ui/login/static/templates/header.html | 4 +- .../login/static/templates/init_password.html | 50 +- .../static/templates/init_password_done.html | 12 +- .../ui/login/static/templates/init_user.html | 55 +- .../static/templates/init_user_done.html | 14 +- .../static/templates/link_users_done.html | 12 +- internal/ui/login/static/templates/login.html | 50 +- .../login/static/templates/logout_done.html | 8 +- .../static/templates/mail_verification.html | 28 +- .../login/static/templates/mail_verified.html | 14 +- internal/ui/login/static/templates/main.html | 35 +- .../login/static/templates/mfa_init_done.html | 14 +- .../login/static/templates/mfa_init_u2f.html | 19 +- .../static/templates/mfa_init_verify.html | 53 +- .../ui/login/static/templates/mfa_prompt.html | 26 +- .../templates/mfa_verification_u2f.html | 35 +- .../ui/login/static/templates/mfa_verify.html | 47 +- .../ui/login/static/templates/password.html | 33 +- .../static/templates/password_reset_done.html | 11 +- .../login/static/templates/passwordless.html | 27 +- .../ui/login/static/templates/register.html | 127 +- .../static/templates/register_option.html | 25 +- .../login/static/templates/register_org.html | 111 +- .../login/static/templates/select_user.html | 65 +- .../login/static/templates/user_profile.html | 24 +- .../user/repository/view/model/notify_user.go | 2 +- internal/v2/command/setup_step10.go | 45 + internal/v2/domain/step.go | 1 + internal/view/repository/sequence.go | 31 +- migrations/cockroach/V1.0__databases.sql | 12 +- ...chine.sql => V1.10__user_machine_keys.sql} | 3 +- .../cockroach/V1.14__auth_loginpolicy.sql | 7 +- migrations/cockroach/V1.1__eventstore.sql | 2 + .../V1.27__database_and_table_ownership.sql | 82 + migrations/cockroach/V1.28__templates.sql | 83 + migrations/cockroach/clean_cluster.go | 5 - migrations/cockroach/clean_local.go | 5 - migrations/cockroach/migrate_cluster.go | 5 - migrations/testfiles/1.2__not.sql | 1 + migrations/testfiles/V1.1__test.sql | 1 + migrations/testfiles/V1.2__test2.sql | 1 + migrations/testfiles/V1.3__empty.sql | 0 operator/adapt.go | 113 + operator/api/api.go | 83 + operator/common/yaml.go | 25 + operator/database/kinds/backups/backups.go | 71 + .../database/kinds/backups/bucket/adapt.go | 230 + .../kinds/backups/bucket/adapt_test.go | 372 ++ .../kinds/backups/bucket/backup/adapt.go | 136 + .../kinds/backups/bucket/backup/adapt_test.go | 307 ++ .../kinds/backups/bucket/backup/cleanup.go | 25 + .../backups/bucket/backup/cleanup_test.go | 40 + .../kinds/backups/bucket/backup/command.go | 33 + .../backups/bucket/backup/command_test.go | 53 + .../kinds/backups/bucket/backup/job.go | 101 + .../kinds/backups/bucket/backup/job_test.go | 123 + .../kinds/backups/bucket/clean/adapt.go | 86 + .../kinds/backups/bucket/clean/adapt_test.go | 134 + .../kinds/backups/bucket/clean/cleanup.go | 29 + .../backups/bucket/clean/cleanup_test.go | 40 + .../kinds/backups/bucket/clean/command.go | 32 + .../backups/bucket/clean/command_test.go | 35 + .../kinds/backups/bucket/clean/job.go | 73 + .../kinds/backups/bucket/clean/job_test.go | 164 + .../database/kinds/backups/bucket/desired.go | 42 + .../kinds/backups/bucket/desired_test.go | 129 + .../database/kinds/backups/bucket/list.go | 63 + .../database/kinds/backups/bucket/mock.go | 97 + .../kinds/backups/bucket/restore/adapt.go | 95 + .../backups/bucket/restore/adapt_test.go | 148 + .../kinds/backups/bucket/restore/cleanup.go | 25 + .../backups/bucket/restore/cleanup_test.go | 40 + .../kinds/backups/bucket/restore/command.go | 28 + .../backups/bucket/restore/command_test.go | 50 + .../kinds/backups/bucket/restore/job.go | 72 + .../kinds/backups/bucket/restore/job_test.go | 163 + .../database/kinds/backups/bucket/secrets.go | 19 + .../kinds/backups/bucket/secrets_test.go | 22 + operator/database/kinds/backups/core/list.go | 8 + .../database/kinds/databases/core/current.go | 64 + .../database/kinds/databases/core/dblist.go | 65 + .../database/kinds/databases/core/generate.go | 3 + .../kinds/databases/core/mock/current.mock.go | 186 + .../database/kinds/databases/databases.go | 68 + .../database/kinds/databases/managed/adapt.go | 256 + .../databases/managed/adapt_backup_test.go | 177 + .../kinds/databases/managed/adapt_test.go | 255 + .../databases/managed/certificate/adapt.go | 91 + .../managed/certificate/adapt_test.go | 305 ++ .../certificate/certificates/certificates.go | 111 + .../certificates/certificates_test.go | 54 + .../managed/certificate/client/adapt.go | 101 + .../managed/certificate/client/adapt_test.go | 169 + .../managed/certificate/client/query.go | 32 + .../managed/certificate/client/query_test.go | 95 + .../databases/managed/certificate/current.go | 10 + .../managed/certificate/node/adapt.go | 150 + .../managed/certificate/node/adapt_test.go | 245 + .../databases/managed/certificate/pem/pem.go | 48 + .../kinds/databases/managed/current.go | 73 + .../kinds/databases/managed/database/adapt.go | 50 + .../kinds/databases/managed/desired.go | 39 + .../kinds/databases/managed/listbackups.go | 36 + .../kinds/databases/managed/rbac/adapt.go | 106 + .../databases/managed/rbac/adapt_test.go | 207 + .../kinds/databases/managed/services/adapt.go | 79 + .../databases/managed/services/adapt_test.go | 218 + .../databases/managed/statefulset/adapt.go | 352 ++ .../managed/statefulset/adapt_test.go | 506 ++ .../kinds/databases/managed/user/adapt.go | 72 + .../kinds/databases/provided/adapt.go | 59 + .../kinds/databases/provided/current.go | 21 + .../kinds/databases/provided/desired.go | 32 + operator/database/kinds/orb/adapt.go | 110 + operator/database/kinds/orb/backups.go | 24 + operator/database/kinds/orb/desired.go | 33 + operator/database/kinds/orb/labels.go | 13 + operator/database/kinds/orb/reconcile.go | 48 + operator/database/takeoff.go | 45 + operator/helpers/intstr.go | 13 + operator/helpers/path.go | 17 + operator/helpers/pointers.go | 16 + operator/secrets/secrets.go | 97 + operator/start/start.go | 155 + operator/zitadel/kinds/iam/iam.go | 49 + operator/zitadel/kinds/iam/zitadel/adapt.go | 280 ++ .../kinds/iam/zitadel/ambassador/adapt.go | 69 + .../iam/zitadel/ambassador/adapt_test.go | 146 + .../iam/zitadel/ambassador/grpc/adapt.go | 127 + .../iam/zitadel/ambassador/grpc/adapt_test.go | 268 ++ .../iam/zitadel/ambassador/hosts/adapt.go | 113 + .../zitadel/ambassador/hosts/adapt_test.go | 379 ++ .../iam/zitadel/ambassador/http/adapt.go | 225 + .../iam/zitadel/ambassador/http/adapt_test.go | 451 ++ .../kinds/iam/zitadel/ambassador/ui/adapt.go | 95 + .../iam/zitadel/ambassador/ui/adapt_test.go | 203 + .../kinds/iam/zitadel/configuration/adapt.go | 182 + .../iam/zitadel/configuration/adapt_test.go | 325 ++ .../iam/zitadel/configuration/desired.go | 83 + .../kinds/iam/zitadel/configuration/hash.go | 16 + .../iam/zitadel/configuration/literals.go | 183 + .../zitadel/configuration/literals_test.go | 425 ++ .../kinds/iam/zitadel/configuration/ready.go | 42 + .../iam/zitadel/configuration/ready_test.go | 157 + .../iam/zitadel/configuration/users/adapt.go | 66 + .../zitadel/configuration/users/adapt_test.go | 122 + .../iam/zitadel/configuration/users/users.go | 40 + .../zitadel/configuration/users/users_test.go | 60 + .../kinds/iam/zitadel/database/adapt.go | 41 + .../kinds/iam/zitadel/database/adapt_test.go | 121 + .../kinds/iam/zitadel/database/client.go | 56 + .../kinds/iam/zitadel/database/database.go | 24 + .../kinds/iam/zitadel/database/generate.go | 3 + .../iam/zitadel/database/mock/client.mock.go | 94 + .../kinds/iam/zitadel/database/user.go | 33 + .../kinds/iam/zitadel/deployment/adapt.go | 182 + .../iam/zitadel/deployment/adapt_test.go | 161 + .../kinds/iam/zitadel/deployment/container.go | 131 + .../iam/zitadel/deployment/container_test.go | 154 + .../iam/zitadel/deployment/initcontainer.go | 52 + .../zitadel/deployment/initcontainer_test.go | 101 + .../kinds/iam/zitadel/deployment/ready.go | 21 + .../iam/zitadel/deployment/ready_test.go | 57 + .../kinds/iam/zitadel/deployment/resources.go | 24 + .../iam/zitadel/deployment/resources_test.go | 57 + .../kinds/iam/zitadel/deployment/scale.go | 17 + .../iam/zitadel/deployment/scale_test.go | 68 + .../kinds/iam/zitadel/deployment/volumes.go | 73 + .../iam/zitadel/deployment/volumes_test.go | 110 + operator/zitadel/kinds/iam/zitadel/desired.go | 38 + operator/zitadel/kinds/iam/zitadel/labels.go | 11 + .../kinds/iam/zitadel/migration/adapt.go | 241 + .../kinds/iam/zitadel/migration/adapt_test.go | 175 + .../kinds/iam/zitadel/migration/cleanup.go | 24 + .../iam/zitadel/migration/cleanup_test.go | 58 + .../kinds/iam/zitadel/migration/done.go | 30 + .../kinds/iam/zitadel/migration/done_test.go | 58 + .../zitadel/migration/migrationcontainer.go | 57 + .../migration/migrationcontainer_test.go | 113 + .../iam/zitadel/migration/postcontainer.go | 43 + .../zitadel/migration/postcontainer_test.go | 20 + .../iam/zitadel/migration/precontainer.go | 82 + .../zitadel/migration/precontainer_test.go | 77 + operator/zitadel/kinds/iam/zitadel/secrets.go | 49 + .../kinds/iam/zitadel/services/adapt.go | 86 + .../kinds/iam/zitadel/services/adapt_test.go | 406 ++ .../kinds/iam/zitadel/services/clientid.go | 27 + .../zitadel/kinds/iam/zitadel/setup/adapt.go | 174 + .../kinds/iam/zitadel/setup/adapt_test.go | 155 + .../zitadel/kinds/iam/zitadel/setup/done.go | 24 + .../kinds/iam/zitadel/setup/done_test.go | 58 + operator/zitadel/kinds/iam/zitadel/users.go | 83 + operator/zitadel/kinds/orb/adapt.go | 101 + operator/zitadel/kinds/orb/desired.go | 33 + operator/zitadel/kinds/orb/labels.go | 13 + operator/zitadel/kinds/orb/reconcile.go | 49 + operator/zitadel/takeoff.go | 47 + pkg/databases/backup.go | 65 + pkg/databases/clear.go | 45 + pkg/databases/connection.go | 40 + pkg/databases/restore.go | 46 + pkg/databases/user.go | 127 + pkg/grpc/admin/mock/admin.proto.mock.go | 80 + pkg/grpc/admin/proto/admin.proto | 99 + pkg/grpc/auth/mock/auth.proto.mock.go | 20 + .../management/mock/management.proto.mock.go | 240 + pkg/grpc/management/proto/management.proto | 170 + pkg/kubernetes/artifacts.go | 298 ++ scripts/build.sh | 13 + scripts/operator-debug.sh | 8 + scripts/zitadelctl-debug.sh | 7 + site/docs/documentation/03-openidoauth.en.md | 16 +- site/package-lock.json | 358 +- site/package.json | 2 +- 646 files changed, 34637 insertions(+), 6507 deletions(-) create mode 100644 .github/workflows/operator.yml rename .github/workflows/{release.yml => zitadel.yml} (97%) create mode 100644 build/console/package-lock.json create mode 100644 build/cr-backup/Dockerfile create mode 100644 build/cr-backup/scripts/backup-cockroach.sh create mode 100644 build/cr-backup/scripts/clean-db-cockroach.sh create mode 100644 build/cr-backup/scripts/clean-migration-cockroach.sh create mode 100644 build/cr-backup/scripts/clean-user-cockroach.sh create mode 100644 build/cr-backup/scripts/restore-cockroach.sh create mode 100644 build/operator/.dockerignore create mode 100644 build/operator/Dockerfile create mode 100755 build/operator/prebuild.sh create mode 100644 changelog.config.js create mode 100644 cmd/database-debug/main.go create mode 100644 cmd/operator-debug/main.go create mode 100644 cmd/zitadelctl/cmds/backup.go create mode 100644 cmd/zitadelctl/cmds/backuplist.go create mode 100644 cmd/zitadelctl/cmds/readsecret.go create mode 100644 cmd/zitadelctl/cmds/restore.go create mode 100644 cmd/zitadelctl/cmds/root.go create mode 100644 cmd/zitadelctl/cmds/start.go create mode 100644 cmd/zitadelctl/cmds/takeoff.go create mode 100644 cmd/zitadelctl/cmds/writesecret.go create mode 100644 cmd/zitadelctl/main.go create mode 100644 console/src/app/favicon-96x96.ico create mode 100644 internal/admin/repository/eventsourcing/handler/mail_template.go create mode 100644 internal/admin/repository/eventsourcing/handler/mail_text.go create mode 100644 internal/admin/repository/eventsourcing/view/mail_templates.go create mode 100644 internal/admin/repository/eventsourcing/view/mail_texts.go create mode 100644 internal/api/grpc/admin/template.go create mode 100644 internal/api/grpc/admin/template_converter.go create mode 100644 internal/api/grpc/admin/text.go create mode 100644 internal/api/grpc/admin/text_converter.go create mode 100644 internal/api/grpc/management/mail_template.go create mode 100644 internal/api/grpc/management/mail_template_converter.go create mode 100644 internal/api/grpc/management/mail_text.go create mode 100644 internal/api/grpc/management/mail_text_converter.go create mode 100644 internal/iam/model/mail_template.go create mode 100644 internal/iam/model/mail_template_view.go create mode 100644 internal/iam/model/mail_text.go create mode 100644 internal/iam/model/mail_text_view.go create mode 100644 internal/iam/repository/eventsourcing/model/mail_template.go create mode 100644 internal/iam/repository/eventsourcing/model/mail_template_test.go create mode 100644 internal/iam/repository/eventsourcing/model/mail_text.go create mode 100644 internal/iam/repository/eventsourcing/model/mail_text_test.go create mode 100644 internal/iam/repository/view/mail_template_view.go create mode 100644 internal/iam/repository/view/mail_text_view.go create mode 100644 internal/iam/repository/view/model/mail_template.go create mode 100644 internal/iam/repository/view/model/mail_template_query.go create mode 100644 internal/iam/repository/view/model/mail_text.go create mode 100644 internal/iam/repository/view/model/mail_text_query.go create mode 100644 internal/management/repository/eventsourcing/handler/mail_template.go create mode 100644 internal/management/repository/eventsourcing/handler/mail_text.go create mode 100644 internal/management/repository/eventsourcing/view/mail_templates.go create mode 100644 internal/management/repository/eventsourcing/view/mail_texts.go create mode 100644 internal/notification/repository/eventsourcing/view/mail_template.go create mode 100644 internal/notification/repository/eventsourcing/view/mail_text.go create mode 100644 internal/org/repository/eventsourcing/mail_template.go create mode 100644 internal/org/repository/eventsourcing/mail_template_test.go create mode 100644 internal/org/repository/eventsourcing/mail_text.go create mode 100644 internal/org/repository/eventsourcing/mail_text_test.go create mode 100644 internal/org/repository/eventsourcing/model/mail_template.go create mode 100644 internal/org/repository/eventsourcing/model/mail_template_test.go create mode 100644 internal/org/repository/eventsourcing/model/mail_text.go create mode 100644 internal/org/repository/eventsourcing/model/mail_text_test.go create mode 100644 internal/setup/step10.go create mode 100644 internal/ui/login/static/resources/fonts/PT_Sans/PTSans-Bold.ttf create mode 100644 internal/ui/login/static/resources/fonts/PT_Sans/PTSans-BoldItalic.ttf create mode 100644 internal/ui/login/static/resources/fonts/PT_Sans/PTSans-Italic.ttf create mode 100644 internal/ui/login/static/resources/fonts/PT_Sans/PTSans-Regular.ttf create mode 100644 internal/ui/login/static/resources/fonts/Raleway/Raleway-Black.ttf create mode 100644 internal/ui/login/static/resources/fonts/Raleway/Raleway-BlackItalic.ttf create mode 100644 internal/ui/login/static/resources/fonts/Raleway/Raleway-Bold.ttf create mode 100644 internal/ui/login/static/resources/fonts/Raleway/Raleway-BoldItalic.ttf create mode 100644 internal/ui/login/static/resources/fonts/Raleway/Raleway-ExtraBold.ttf create mode 100644 internal/ui/login/static/resources/fonts/Raleway/Raleway-ExtraBoldItalic.ttf create mode 100644 internal/ui/login/static/resources/fonts/Raleway/Raleway-ExtraLight.ttf create mode 100644 internal/ui/login/static/resources/fonts/Raleway/Raleway-ExtraLightItalic.ttf create mode 100644 internal/ui/login/static/resources/fonts/Raleway/Raleway-Italic.ttf create mode 100644 internal/ui/login/static/resources/fonts/Raleway/Raleway-Light.ttf create mode 100644 internal/ui/login/static/resources/fonts/Raleway/Raleway-LightItalic.ttf create mode 100644 internal/ui/login/static/resources/fonts/Raleway/Raleway-Medium.ttf create mode 100644 internal/ui/login/static/resources/fonts/Raleway/Raleway-MediumItalic.ttf create mode 100644 internal/ui/login/static/resources/fonts/Raleway/Raleway-Regular.ttf create mode 100644 internal/ui/login/static/resources/fonts/Raleway/Raleway-SemiBold.ttf create mode 100644 internal/ui/login/static/resources/fonts/Raleway/Raleway-SemiBoldItalic.ttf create mode 100644 internal/ui/login/static/resources/fonts/Raleway/Raleway-Thin.ttf create mode 100644 internal/ui/login/static/resources/fonts/Raleway/Raleway-ThinItalic.ttf create mode 100644 internal/ui/login/static/resources/fonts/Roboto/Roboto-Black.ttf create mode 100644 internal/ui/login/static/resources/fonts/Roboto/Roboto-BlackItalic.ttf create mode 100644 internal/ui/login/static/resources/fonts/Roboto/Roboto-Bold.ttf create mode 100644 internal/ui/login/static/resources/fonts/Roboto/Roboto-BoldItalic.ttf create mode 100644 internal/ui/login/static/resources/fonts/Roboto/Roboto-Italic.ttf create mode 100644 internal/ui/login/static/resources/fonts/Roboto/Roboto-Light.ttf create mode 100644 internal/ui/login/static/resources/fonts/Roboto/Roboto-LightItalic.ttf create mode 100644 internal/ui/login/static/resources/fonts/Roboto/Roboto-Medium.ttf create mode 100644 internal/ui/login/static/resources/fonts/Roboto/Roboto-MediumItalic.ttf create mode 100644 internal/ui/login/static/resources/fonts/Roboto/Roboto-Regular.ttf create mode 100644 internal/ui/login/static/resources/fonts/Roboto/Roboto-Thin.ttf create mode 100644 internal/ui/login/static/resources/fonts/Roboto/Roboto-ThinItalic.ttf create mode 100644 internal/ui/login/static/resources/fonts/lgn-icons/css/lgn-icon-font.css create mode 100644 internal/ui/login/static/resources/fonts/lgn-icons/fonts/lgn-icons.eot create mode 100644 internal/ui/login/static/resources/fonts/lgn-icons/fonts/lgn-icons.svg create mode 100644 internal/ui/login/static/resources/fonts/lgn-icons/fonts/lgn-icons.ttf create mode 100644 internal/ui/login/static/resources/fonts/lgn-icons/fonts/lgn-icons.woff create mode 100755 internal/ui/login/static/resources/fonts/lgn-icons/svg/angle-left-solid.svg create mode 100755 internal/ui/login/static/resources/fonts/lgn-icons/svg/angle-right-solid.svg create mode 100755 internal/ui/login/static/resources/fonts/lgn-icons/svg/arrow-left-solid.svg create mode 100755 internal/ui/login/static/resources/fonts/lgn-icons/svg/arrow-right-solid.svg create mode 100755 internal/ui/login/static/resources/fonts/lgn-icons/svg/check-solid.svg create mode 100755 internal/ui/login/static/resources/fonts/lgn-icons/svg/clipboard-check-solid.svg create mode 100755 internal/ui/login/static/resources/fonts/lgn-icons/svg/clipboard-solid.svg create mode 100755 internal/ui/login/static/resources/fonts/lgn-icons/svg/exclamation-circle-solid.svg create mode 100755 internal/ui/login/static/resources/fonts/lgn-icons/svg/times-solid.svg create mode 100755 internal/ui/login/static/resources/fonts/lgn-icons/svg/user-plus-solid.svg delete mode 100644 internal/ui/login/static/resources/fonts/material/MaterialIcons-Regular.eot delete mode 100644 internal/ui/login/static/resources/fonts/material/MaterialIcons-Regular.ttf delete mode 100644 internal/ui/login/static/resources/fonts/material/MaterialIcons-Regular.woff delete mode 100644 internal/ui/login/static/resources/fonts/material/MaterialIcons-Regular.woff2 delete mode 100644 internal/ui/login/static/resources/images/icon-newuser-dark-hover.png delete mode 100644 internal/ui/login/static/resources/images/icon-newuser-dark-hover@2x.png delete mode 100644 internal/ui/login/static/resources/images/icon-newuser-dark.png delete mode 100644 internal/ui/login/static/resources/images/icon-newuser-dark@2x.png delete mode 100644 internal/ui/login/static/resources/images/icon-newuser-light-hover.png delete mode 100644 internal/ui/login/static/resources/images/icon-newuser-light-hover@2x.png delete mode 100644 internal/ui/login/static/resources/images/icon-newuser-light.png delete mode 100644 internal/ui/login/static/resources/images/icon-newuser-light@2x.png delete mode 100644 internal/ui/login/static/resources/images/icon-user-dark-hover.png delete mode 100644 internal/ui/login/static/resources/images/icon-user-dark-hover@2x.png delete mode 100644 internal/ui/login/static/resources/images/icon-user-dark.png delete mode 100644 internal/ui/login/static/resources/images/icon-user-dark@2x.png delete mode 100644 internal/ui/login/static/resources/images/icon-user-light-hover.png delete mode 100644 internal/ui/login/static/resources/images/icon-user-light-hover@2x.png delete mode 100644 internal/ui/login/static/resources/images/icon-user-light.png delete mode 100644 internal/ui/login/static/resources/images/icon-user-light@2x.png create mode 100644 internal/ui/login/static/resources/scripts/avatar.js create mode 100644 internal/ui/login/static/resources/scripts/input_suffix_offset.js create mode 100644 internal/ui/login/static/resources/scripts/theme.js delete mode 100644 internal/ui/login/static/resources/themes/caos/css/dark.css delete mode 100644 internal/ui/login/static/resources/themes/caos/css/dark.css.map delete mode 100644 internal/ui/login/static/resources/themes/caos/css/light.css delete mode 100644 internal/ui/login/static/resources/themes/caos/css/light.css.map delete mode 100644 internal/ui/login/static/resources/themes/caos/favicon.ico delete mode 100644 internal/ui/login/static/resources/themes/caos/gradientdeco-full.svg delete mode 100644 internal/ui/login/static/resources/themes/caos/logo-dark.png delete mode 100644 internal/ui/login/static/resources/themes/caos/logo-light.png create mode 100644 internal/ui/login/static/resources/themes/scss/bundle.scss delete mode 100644 internal/ui/login/static/resources/themes/scss/caos/dark.scss delete mode 100644 internal/ui/login/static/resources/themes/scss/caos/light.scss delete mode 100644 internal/ui/login/static/resources/themes/scss/caos/variables.scss delete mode 100644 internal/ui/login/static/resources/themes/scss/light.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/a/a.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/a/a_theme.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/account_selection/account_selection.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/account_selection/account_selection_theme.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/animations.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/avatar/avatar.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/avatar/avatar_theme.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/button/button.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/button/button_base.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/button/button_theme.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/checkbox/checkbox.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/checkbox/checkbox_base.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/checkbox/checkbox_theme.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/color/all_color.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/container/container.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/container/container_theme.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/core/core.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/elevation/elevation.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/error/error.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/error/error_theme.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/footer/footer.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/footer/footer_theme.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/header/header.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/header/header_theme.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/identity_provider/identity_provider.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/identity_provider/identity_provider_base.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/identity_provider/identity_provider_theme.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/input/input.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/input/input_base.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/input/input_theme.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/label/label.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/label/label_base.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/label/label_theme.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/list/list.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/list/list_base.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/list/list_theme.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/progress_bar/progress_bar.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/progress_bar/progress_bar_base.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/progress_bar/progress_bar_theme.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/qrcode/qrcode.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/qrcode/qrcode_theme.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/radio/radio.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/radio/radio_base.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/radio/radio_theme.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/register/register.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/select/select.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/select/select_base.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/select/select_theme.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/success_label/success_label.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/success_label/success_label_base.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/success_label/success_label_theme.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/theming/all.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/theming/palette.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/theming/theming.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/typography/faces/ailerons_font_faces.scss rename internal/ui/login/static/resources/themes/scss/{fonts.scss => styles/typography/faces/lato_font_faces.scss} (71%) create mode 100644 internal/ui/login/static/resources/themes/scss/styles/typography/faces/pt_sans_font_faces.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/typography/faces/raleway_font_faces.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/typography/faces/roboto_font_faces.scss create mode 100644 internal/ui/login/static/resources/themes/scss/styles/typography/typography.scss delete mode 100644 internal/ui/login/static/resources/themes/scss/variables.scss create mode 100644 internal/ui/login/static/resources/themes/scss/zitadel-alternative.scss create mode 100644 internal/ui/login/static/resources/themes/scss/zitadel.scss delete mode 100644 internal/ui/login/static/resources/themes/scss/zitadel/dark.scss delete mode 100644 internal/ui/login/static/resources/themes/scss/zitadel/light.scss delete mode 100644 internal/ui/login/static/resources/themes/scss/zitadel/variables.scss create mode 100644 internal/ui/login/static/resources/themes/zitadel/css/bundle.css create mode 100644 internal/ui/login/static/resources/themes/zitadel/css/bundle.css.map delete mode 100644 internal/ui/login/static/resources/themes/zitadel/css/dark.css delete mode 100644 internal/ui/login/static/resources/themes/zitadel/css/dark.css.map delete mode 100644 internal/ui/login/static/resources/themes/zitadel/css/light.css delete mode 100644 internal/ui/login/static/resources/themes/zitadel/css/light.css.map create mode 100644 internal/ui/login/static/resources/themes/zitadel/css/main.css create mode 100644 internal/ui/login/static/resources/themes/zitadel/css/main.css.map create mode 100644 internal/ui/login/static/resources/themes/zitadel/css/zitadel.css create mode 100644 internal/ui/login/static/resources/themes/zitadel/css/zitadel.css.map delete mode 100644 internal/ui/login/static/resources/themes/zitadel/logo-dark.png create mode 100644 internal/ui/login/static/resources/themes/zitadel/logo-dark.svg delete mode 100644 internal/ui/login/static/resources/themes/zitadel/logo-light.png create mode 100644 internal/ui/login/static/resources/themes/zitadel/logo-light.svg create mode 100644 internal/ui/login/static/resources/themes/zitadel/select_arrow_dark.svg create mode 100644 internal/ui/login/static/resources/themes/zitadel/select_arrow_light.svg create mode 100644 internal/v2/command/setup_step10.go rename migrations/cockroach/{V1.10__user_machine.sql => V1.10__user_machine_keys.sql} (99%) create mode 100644 migrations/cockroach/V1.27__database_and_table_ownership.sql create mode 100644 migrations/cockroach/V1.28__templates.sql delete mode 100644 migrations/cockroach/clean_cluster.go delete mode 100644 migrations/cockroach/clean_local.go delete mode 100644 migrations/cockroach/migrate_cluster.go create mode 100644 migrations/testfiles/1.2__not.sql create mode 100644 migrations/testfiles/V1.1__test.sql create mode 100644 migrations/testfiles/V1.2__test2.sql create mode 100644 migrations/testfiles/V1.3__empty.sql create mode 100644 operator/adapt.go create mode 100644 operator/api/api.go create mode 100644 operator/common/yaml.go create mode 100644 operator/database/kinds/backups/backups.go create mode 100644 operator/database/kinds/backups/bucket/adapt.go create mode 100644 operator/database/kinds/backups/bucket/adapt_test.go create mode 100644 operator/database/kinds/backups/bucket/backup/adapt.go create mode 100644 operator/database/kinds/backups/bucket/backup/adapt_test.go create mode 100644 operator/database/kinds/backups/bucket/backup/cleanup.go create mode 100644 operator/database/kinds/backups/bucket/backup/cleanup_test.go create mode 100644 operator/database/kinds/backups/bucket/backup/command.go create mode 100644 operator/database/kinds/backups/bucket/backup/command_test.go create mode 100644 operator/database/kinds/backups/bucket/backup/job.go create mode 100644 operator/database/kinds/backups/bucket/backup/job_test.go create mode 100644 operator/database/kinds/backups/bucket/clean/adapt.go create mode 100644 operator/database/kinds/backups/bucket/clean/adapt_test.go create mode 100644 operator/database/kinds/backups/bucket/clean/cleanup.go create mode 100644 operator/database/kinds/backups/bucket/clean/cleanup_test.go create mode 100644 operator/database/kinds/backups/bucket/clean/command.go create mode 100644 operator/database/kinds/backups/bucket/clean/command_test.go create mode 100644 operator/database/kinds/backups/bucket/clean/job.go create mode 100644 operator/database/kinds/backups/bucket/clean/job_test.go create mode 100644 operator/database/kinds/backups/bucket/desired.go create mode 100644 operator/database/kinds/backups/bucket/desired_test.go create mode 100644 operator/database/kinds/backups/bucket/list.go create mode 100644 operator/database/kinds/backups/bucket/mock.go create mode 100644 operator/database/kinds/backups/bucket/restore/adapt.go create mode 100644 operator/database/kinds/backups/bucket/restore/adapt_test.go create mode 100644 operator/database/kinds/backups/bucket/restore/cleanup.go create mode 100644 operator/database/kinds/backups/bucket/restore/cleanup_test.go create mode 100644 operator/database/kinds/backups/bucket/restore/command.go create mode 100644 operator/database/kinds/backups/bucket/restore/command_test.go create mode 100644 operator/database/kinds/backups/bucket/restore/job.go create mode 100644 operator/database/kinds/backups/bucket/restore/job_test.go create mode 100644 operator/database/kinds/backups/bucket/secrets.go create mode 100644 operator/database/kinds/backups/bucket/secrets_test.go create mode 100644 operator/database/kinds/backups/core/list.go create mode 100644 operator/database/kinds/databases/core/current.go create mode 100644 operator/database/kinds/databases/core/dblist.go create mode 100644 operator/database/kinds/databases/core/generate.go create mode 100644 operator/database/kinds/databases/core/mock/current.mock.go create mode 100644 operator/database/kinds/databases/databases.go create mode 100644 operator/database/kinds/databases/managed/adapt.go create mode 100644 operator/database/kinds/databases/managed/adapt_backup_test.go create mode 100644 operator/database/kinds/databases/managed/adapt_test.go create mode 100644 operator/database/kinds/databases/managed/certificate/adapt.go create mode 100644 operator/database/kinds/databases/managed/certificate/adapt_test.go create mode 100644 operator/database/kinds/databases/managed/certificate/certificates/certificates.go create mode 100644 operator/database/kinds/databases/managed/certificate/certificates/certificates_test.go create mode 100644 operator/database/kinds/databases/managed/certificate/client/adapt.go create mode 100644 operator/database/kinds/databases/managed/certificate/client/adapt_test.go create mode 100644 operator/database/kinds/databases/managed/certificate/client/query.go create mode 100644 operator/database/kinds/databases/managed/certificate/client/query_test.go create mode 100644 operator/database/kinds/databases/managed/certificate/current.go create mode 100644 operator/database/kinds/databases/managed/certificate/node/adapt.go create mode 100644 operator/database/kinds/databases/managed/certificate/node/adapt_test.go create mode 100644 operator/database/kinds/databases/managed/certificate/pem/pem.go create mode 100644 operator/database/kinds/databases/managed/current.go create mode 100644 operator/database/kinds/databases/managed/database/adapt.go create mode 100644 operator/database/kinds/databases/managed/desired.go create mode 100644 operator/database/kinds/databases/managed/listbackups.go create mode 100644 operator/database/kinds/databases/managed/rbac/adapt.go create mode 100644 operator/database/kinds/databases/managed/rbac/adapt_test.go create mode 100644 operator/database/kinds/databases/managed/services/adapt.go create mode 100644 operator/database/kinds/databases/managed/services/adapt_test.go create mode 100644 operator/database/kinds/databases/managed/statefulset/adapt.go create mode 100644 operator/database/kinds/databases/managed/statefulset/adapt_test.go create mode 100644 operator/database/kinds/databases/managed/user/adapt.go create mode 100644 operator/database/kinds/databases/provided/adapt.go create mode 100644 operator/database/kinds/databases/provided/current.go create mode 100644 operator/database/kinds/databases/provided/desired.go create mode 100644 operator/database/kinds/orb/adapt.go create mode 100644 operator/database/kinds/orb/backups.go create mode 100644 operator/database/kinds/orb/desired.go create mode 100644 operator/database/kinds/orb/labels.go create mode 100644 operator/database/kinds/orb/reconcile.go create mode 100644 operator/database/takeoff.go create mode 100644 operator/helpers/intstr.go create mode 100644 operator/helpers/path.go create mode 100644 operator/helpers/pointers.go create mode 100644 operator/secrets/secrets.go create mode 100644 operator/start/start.go create mode 100644 operator/zitadel/kinds/iam/iam.go create mode 100644 operator/zitadel/kinds/iam/zitadel/adapt.go create mode 100644 operator/zitadel/kinds/iam/zitadel/ambassador/adapt.go create mode 100644 operator/zitadel/kinds/iam/zitadel/ambassador/adapt_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/ambassador/grpc/adapt.go create mode 100644 operator/zitadel/kinds/iam/zitadel/ambassador/grpc/adapt_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/ambassador/hosts/adapt.go create mode 100644 operator/zitadel/kinds/iam/zitadel/ambassador/hosts/adapt_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/ambassador/http/adapt.go create mode 100644 operator/zitadel/kinds/iam/zitadel/ambassador/http/adapt_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/ambassador/ui/adapt.go create mode 100644 operator/zitadel/kinds/iam/zitadel/ambassador/ui/adapt_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/configuration/adapt.go create mode 100644 operator/zitadel/kinds/iam/zitadel/configuration/adapt_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/configuration/desired.go create mode 100644 operator/zitadel/kinds/iam/zitadel/configuration/hash.go create mode 100644 operator/zitadel/kinds/iam/zitadel/configuration/literals.go create mode 100644 operator/zitadel/kinds/iam/zitadel/configuration/literals_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/configuration/ready.go create mode 100644 operator/zitadel/kinds/iam/zitadel/configuration/ready_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/configuration/users/adapt.go create mode 100644 operator/zitadel/kinds/iam/zitadel/configuration/users/adapt_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/configuration/users/users.go create mode 100644 operator/zitadel/kinds/iam/zitadel/configuration/users/users_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/database/adapt.go create mode 100644 operator/zitadel/kinds/iam/zitadel/database/adapt_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/database/client.go create mode 100644 operator/zitadel/kinds/iam/zitadel/database/database.go create mode 100644 operator/zitadel/kinds/iam/zitadel/database/generate.go create mode 100644 operator/zitadel/kinds/iam/zitadel/database/mock/client.mock.go create mode 100644 operator/zitadel/kinds/iam/zitadel/database/user.go create mode 100644 operator/zitadel/kinds/iam/zitadel/deployment/adapt.go create mode 100644 operator/zitadel/kinds/iam/zitadel/deployment/adapt_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/deployment/container.go create mode 100644 operator/zitadel/kinds/iam/zitadel/deployment/container_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/deployment/initcontainer.go create mode 100644 operator/zitadel/kinds/iam/zitadel/deployment/initcontainer_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/deployment/ready.go create mode 100644 operator/zitadel/kinds/iam/zitadel/deployment/ready_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/deployment/resources.go create mode 100644 operator/zitadel/kinds/iam/zitadel/deployment/resources_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/deployment/scale.go create mode 100644 operator/zitadel/kinds/iam/zitadel/deployment/scale_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/deployment/volumes.go create mode 100644 operator/zitadel/kinds/iam/zitadel/deployment/volumes_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/desired.go create mode 100644 operator/zitadel/kinds/iam/zitadel/labels.go create mode 100644 operator/zitadel/kinds/iam/zitadel/migration/adapt.go create mode 100644 operator/zitadel/kinds/iam/zitadel/migration/adapt_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/migration/cleanup.go create mode 100644 operator/zitadel/kinds/iam/zitadel/migration/cleanup_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/migration/done.go create mode 100644 operator/zitadel/kinds/iam/zitadel/migration/done_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/migration/migrationcontainer.go create mode 100644 operator/zitadel/kinds/iam/zitadel/migration/migrationcontainer_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/migration/postcontainer.go create mode 100644 operator/zitadel/kinds/iam/zitadel/migration/postcontainer_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/migration/precontainer.go create mode 100644 operator/zitadel/kinds/iam/zitadel/migration/precontainer_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/secrets.go create mode 100644 operator/zitadel/kinds/iam/zitadel/services/adapt.go create mode 100644 operator/zitadel/kinds/iam/zitadel/services/adapt_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/services/clientid.go create mode 100644 operator/zitadel/kinds/iam/zitadel/setup/adapt.go create mode 100644 operator/zitadel/kinds/iam/zitadel/setup/adapt_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/setup/done.go create mode 100644 operator/zitadel/kinds/iam/zitadel/setup/done_test.go create mode 100644 operator/zitadel/kinds/iam/zitadel/users.go create mode 100644 operator/zitadel/kinds/orb/adapt.go create mode 100644 operator/zitadel/kinds/orb/desired.go create mode 100644 operator/zitadel/kinds/orb/labels.go create mode 100644 operator/zitadel/kinds/orb/reconcile.go create mode 100644 operator/zitadel/takeoff.go create mode 100644 pkg/databases/backup.go create mode 100644 pkg/databases/clear.go create mode 100644 pkg/databases/connection.go create mode 100644 pkg/databases/restore.go create mode 100644 pkg/databases/user.go create mode 100644 pkg/kubernetes/artifacts.go create mode 100755 scripts/build.sh create mode 100755 scripts/operator-debug.sh create mode 100755 scripts/zitadelctl-debug.sh diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e398907d3b..b482691e32 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -17,7 +17,15 @@ updates: prefix: chore include: scope - package-ecosystem: "docker" - directory: "/build/" + directory: "/build" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + commit-message: + prefix: chore + include: scope +- package-ecosystem: "docker" + directory: "/build/operator" schedule: interval: "weekly" open-pull-requests-limit: 10 diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index e969fc7362..51d6029fe4 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -19,6 +19,13 @@ jobs: key: ${{ runner.os }}-buildx-${{ github.sha }} restore-keys: | ${{ runner.os }}-buildx- + - name: Cache Docker layers + uses: actions/cache@v2 + with: + path: /tmp/.buildx-cache-op + key: ${{ runner.os }}-buildx-op-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx-op- - name: Set up QEMU uses: docker/setup-qemu-action@v1 - name: Set up Docker Buildx @@ -32,8 +39,18 @@ jobs: push: false cache-from: type=local,src=/tmp/.buildx-cache target: go-codecov - outputs: type=local,dest=. + outputs: type=local,dest=/tmp/zitadel + - uses: docker/build-push-action@v2 + with: + context: . + file: ./build/operator/Dockerfile + platforms: linux/amd64 + tags: ${{ env.REGISTRY }}/${{ github.repository }}:coverage + push: false + cache-from: type=local,src=/tmp/.buildx-cache-op + target: go-codecov + outputs: type=local,dest=/tmp/operator - uses: codecov/codecov-action@v1 with: - file: ./profile.cov + files: /tmp/zitadel/profile.cov,/tmp/operator/profile.cov name: codecov-go \ No newline at end of file diff --git a/.github/workflows/operator.yml b/.github/workflows/operator.yml new file mode 100644 index 0000000000..99bbe1ba50 --- /dev/null +++ b/.github/workflows/operator.yml @@ -0,0 +1,165 @@ +name: Operator Release +on: push + +env: + GITHUB_TOKEN: ${{ secrets.CR_PAT }} + REGISTRY: ghcr.io + GO_VERSION: '1.15' + DOCKER_IMAGE_NAME: ${{ github.repository }}-operator + BACKUP_IMAGE_NAME: ${{ github.repository }}-crbackup + +jobs: + container: + runs-on: ubuntu-18.04 + name: Build ${{ matrix.goos }}-${{ matrix.goarch }} + strategy: + matrix: + goos: [ 'linux', 'darwin', 'windows' ] + goarch: [ 'amd64' ] + steps: + - name: Source checkout + uses: actions/checkout@v2 + - name: Set output + id: branch + run: echo ::set-output name=short_ref::${GITHUB_REF#refs/*/} + - name: Semantic Release + id: semantic + uses: cycjimmy/semantic-release-action@v2 + with: + dry_run: true + semantic_version: 17.0.4 + - name: Set version + id: version + run: | + if ${{ steps.semantic.outputs.new_release_published == 'true' }}; then + echo ::set-output name=version::${{ steps.semantic.outputs.new_release_version }} + else + echo ::set-output name=version::${{ steps.branch.outputs.short_ref }} + fi + - name: Check outputs + run: | + echo ${{ steps.branch.outputs.short_ref }} + echo ${{ steps.version.outputs.version }} + - 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-op-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx-op- + - 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 + name: onlybuild + with: + context: . + file: ./build/operator/Dockerfile + platforms: linux/amd64 + tags: ${{ env.REGISTRY }}/${{ env.DOCKER_IMAGE_NAME }}:${{ steps.vars.outputs.sha_short }},${{ env.REGISTRY }}/${{ env.DOCKER_IMAGE_NAME }}:${{ steps.branch.outputs.short_ref }} + push: false + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,mode=max,dest=/tmp/.buildx-cache + outputs: type=local,dest=/tmp/operator + build-args: | + OS=${{ matrix.goos }} + ARCH=${{ matrix.goarch }} + VERSION=${{ steps.version.outputs.version }} + - uses: actions/upload-artifact@v2 + with: + name: zitadelctl-${{ matrix.goos }}-${{ matrix.goarch }} + path: /tmp/operator/zitadelctl + - uses: docker/build-push-action@v2 + if: ${{ matrix.goos == 'linux' && matrix.goarch == 'amd64' }} + name: buildandpush + with: + context: . + file: ./build/operator/Dockerfile + platforms: linux/amd64 + tags: ${{ env.REGISTRY }}/${{ env.DOCKER_IMAGE_NAME }}:${{ steps.vars.outputs.sha_short }},${{ env.REGISTRY }}/${{ env.DOCKER_IMAGE_NAME }}:${{ 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 + build-args: | + OS=${{ matrix.goos }} + ARCH=${{ matrix.goarch }} + VERSION=${{ steps.version.outputs.version }} + - uses: docker/build-push-action@v2 + if: ${{ matrix.goos == 'linux' && matrix.goarch == 'amd64' }} + name: buildandpushcrbackup + with: + context: . + file: ./build/cr-backup/Dockerfile + platforms: linux/amd64 + tags: ${{ env.REGISTRY }}/${{ env.BACKUP_IMAGE_NAME }}:${{ steps.vars.outputs.sha_short }},${{ env.REGISTRY }}/${{ env.BACKUP_IMAGE_NAME }}:${{ 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: Check output + run: echo ${{ steps.vars.outputs.sha_short }} + - name: Docker Login + run: docker login $REGISTRY -u $GITHUB_ACTOR -p $GITHUB_TOKEN + - name: Docker Pull short-sha + run: docker pull $REGISTRY/$DOCKER_IMAGE_NAME:${{ steps.vars.outputs.sha_short }} + - name: Docker Pull short-sha + run: docker pull $REGISTRY/$BACKUP_IMAGE_NAME:${{ steps.vars.outputs.sha_short }} + - name: Download binaries + uses: actions/download-artifact@v2 + with: + path: .artifacts + - 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/$DOCKER_IMAGE_NAME:${{ steps.vars.outputs.sha_short }} $REGISTRY/$DOCKER_IMAGE_NAME:${{ steps.semantic.outputs.new_release_version }} + docker tag $REGISTRY/$BACKUP_IMAGE_NAME:${{ steps.vars.outputs.sha_short }} $REGISTRY/$BACKUP_IMAGE_NAME:${{ steps.semantic.outputs.new_release_version }} + if: steps.semantic.outputs.new_release_published == 'true' + - name: Docker Tag Latest + run: | + docker tag $REGISTRY/$DOCKER_IMAGE_NAME:${{ steps.vars.outputs.sha_short }} $REGISTRY/$DOCKER_IMAGE_NAME:latest + docker tag $REGISTRY/$BACKUP_IMAGE_NAME:${{ steps.vars.outputs.sha_short }} $REGISTRY/$BACKUP_IMAGE_NAME:latest + if: steps.semantic.outputs.new_release_published == 'true' + - name: Docker Push Version + run: | + docker push $REGISTRY/$DOCKER_IMAGE_NAME:${{ steps.semantic.outputs.new_release_version }} + docker push $REGISTRY/$BACKUP_IMAGE_NAME:${{ steps.semantic.outputs.new_release_version }} + if: steps.semantic.outputs.new_release_published == 'true' + - name: Docker Push Latest + run: | + docker push $REGISTRY/$DOCKER_IMAGE_NAME:latest + docker push $REGISTRY/$BACKUP_IMAGE_NAME:latest + if: steps.semantic.outputs.new_release_published == 'true' diff --git a/.github/workflows/release.yml b/.github/workflows/zitadel.yml similarity index 97% rename from .github/workflows/release.yml rename to .github/workflows/zitadel.yml index 9dee765357..ff30ce0443 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/zitadel.yml @@ -1,4 +1,4 @@ -name: Release +name: Zitadel Release on: push env: @@ -20,7 +20,7 @@ jobs: 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 HEAD)" + run: echo "::set-output name=sha_short::SHA-$(git rev-parse --short=12 HEAD)" - name: Cache Docker layers uses: actions/cache@v2 with: @@ -33,7 +33,7 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 - name: Login to DockerHub - uses: docker/login-action@v1 + uses: docker/login-action@v1 with: username: ${{ github.actor }} password: ${{ secrets.CR_PAT }} @@ -59,7 +59,7 @@ jobs: uses: actions/checkout@v2 - name: Generate Short SHA Container Tag id: vars - run: echo "::set-output name=sha_short::SHA-$(git rev-parse --short HEAD)" + 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 diff --git a/.gitignore b/.gitignore index 1fe6ace8cc..47249c59eb 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *.dll *.so *.dylib +zitadelctl # Test binary, build with `go test -c` *.test @@ -17,6 +18,7 @@ coverage.txt #Debug __debug_bin debug +sandbox.go # IDE .idea @@ -38,11 +40,12 @@ cockroach-data/* #binaries cmd/zitadel/zitadel **/statik/statik.go +zitadelctl # buildfolders and generated js tmp/ console/src/app/proto/generated/ pkg/grpc/*/*.pb.* +pkg/grpc/*/*.swagger.json pkg/grpc/*/mock/*.mock.go -pkg/grpc/*/*.swagger.json \ No newline at end of file diff --git a/.releaserc.js b/.releaserc.js index e1e3a2d036..4e06dce043 100644 --- a/.releaserc.js +++ b/.releaserc.js @@ -3,6 +3,21 @@ module.exports = { plugins: [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", - "@semantic-release/github" + ["@semantic-release/github", { + "assets": [ + { + "path": ".artifacts/zitadel-darwin-amd64/zitadelctl", + "label": "Zitadelctl Darwin x86_64" + }, + { + "path": ".artifacts/zitadel-linux-amd64/zitadelctl", + "label": "Zitadelctl Linux x86_64" + }, + { + "path": ".artifacts/zitadel-windows-amd64/zitadelctl", + "label": "Zitadelctl Windows x86_64" + } + ] + }], ] }; diff --git a/build/console/package-lock.json b/build/console/package-lock.json new file mode 100644 index 0000000000..48e341a095 --- /dev/null +++ b/build/console/package-lock.json @@ -0,0 +1,3 @@ +{ + "lockfileVersion": 1 +} diff --git a/build/cr-backup/Dockerfile b/build/cr-backup/Dockerfile new file mode 100644 index 0000000000..6ff695f1ab --- /dev/null +++ b/build/cr-backup/Dockerfile @@ -0,0 +1,22 @@ +FROM cockroachdb/cockroach:v20.2.3 + +RUN microdnf install curl wget tar gzip + +RUN wget https://storage.googleapis.com/oauth2l/latest/linux_amd64.tgz +RUN tar zxvf linux_amd64.tgz +RUN mv linux_amd64/oauth2l /usr/local/bin/oauth2l && rm -rf linux_amd64 + +COPY build/cr-backup/scripts/backup-cockroach.sh /scripts/backup.sh +RUN chmod +x /scripts/backup.sh + +COPY build/cr-backup/scripts/restore-cockroach.sh /scripts/restore.sh +RUN chmod +x /scripts/restore.sh + +COPY build/cr-backup/scripts/clean-db-cockroach.sh /scripts/clean-db.sh +RUN chmod +x /scripts/clean-db.sh +COPY build/cr-backup/scripts/clean-migration-cockroach.sh /scripts/clean-migration.sh +RUN chmod +x /scripts/clean-migration.sh +COPY build/cr-backup/scripts/clean-user-cockroach.sh /scripts/clean-user.sh +RUN chmod +x /scripts/clean-user.sh + +ENTRYPOINT [ "/cockroach" ] diff --git a/build/cr-backup/scripts/backup-cockroach.sh b/build/cr-backup/scripts/backup-cockroach.sh new file mode 100644 index 0000000000..7f15c7ba1d --- /dev/null +++ b/build/cr-backup/scripts/backup-cockroach.sh @@ -0,0 +1,17 @@ +env=$1 +bucket=$2 +db=$3 +folder=$4 +safile=$5 +certs=$6 +name=$7 + +filenamelocal=zitadel-${db}.sql +filenamebucket=zitadel-${db}-${name}.sql + +/cockroach/cockroach.sh dump --dump-mode=data --certs-dir=${certs} --host=cockroachdb-public:26257 ${db} > ${folder}/${filenamelocal} +curl -X POST \ + -H "$(oauth2l header --json ${safile} cloud-platform)" \ + -H "Content-Type: application/json" \ + --data-binary @${folder}/${filenamelocal} \ + "https://storage.googleapis.com/upload/storage/v1/b/${bucket}/o?uploadType=media&name=${env}/${name}/${filenamebucket}" \ No newline at end of file diff --git a/build/cr-backup/scripts/clean-db-cockroach.sh b/build/cr-backup/scripts/clean-db-cockroach.sh new file mode 100644 index 0000000000..c263004db9 --- /dev/null +++ b/build/cr-backup/scripts/clean-db-cockroach.sh @@ -0,0 +1,4 @@ +certs=$1 +db=$2 + +/cockroach/cockroach.sh sql --certs-dir=${certs} --host=cockroachdb-public:26257 -e "DROP DATABASE IF EXISTS ${db} CASCADE;" diff --git a/build/cr-backup/scripts/clean-migration-cockroach.sh b/build/cr-backup/scripts/clean-migration-cockroach.sh new file mode 100644 index 0000000000..0bce3645b4 --- /dev/null +++ b/build/cr-backup/scripts/clean-migration-cockroach.sh @@ -0,0 +1,3 @@ +certs=$1 + +/cockroach/cockroach.sh sql --certs-dir=${certs} --host=cockroachdb-public:26257 -e "TRUNCATE defaultdb.flyway_schema_history;" \ No newline at end of file diff --git a/build/cr-backup/scripts/clean-user-cockroach.sh b/build/cr-backup/scripts/clean-user-cockroach.sh new file mode 100644 index 0000000000..de00b8fc2f --- /dev/null +++ b/build/cr-backup/scripts/clean-user-cockroach.sh @@ -0,0 +1,4 @@ +certs=$1 +db=$2 + +/cockroach/cockroach.sh sql --certs-dir=${certs} --host=cockroachdb-public:26257 -e "DROP USER IF EXISTS ${db};" \ No newline at end of file diff --git a/build/cr-backup/scripts/restore-cockroach.sh b/build/cr-backup/scripts/restore-cockroach.sh new file mode 100644 index 0000000000..e5d1ec8818 --- /dev/null +++ b/build/cr-backup/scripts/restore-cockroach.sh @@ -0,0 +1,33 @@ +bucket=$1 +env=$2 +name=$3 +db=$4 +safile=$5 +certs=$6 + +urlencode() { + # urlencode + old_lc_collate=$LC_COLLATE + LC_COLLATE=C + + local length="${#1}" + for (( i = 0; i < length; i++ )); do + local c="${1:i:1}" + case $c in + [a-zA-Z0-9.~_-]) printf "$c" ;; + *) printf '%%%02X' "'$c" ;; + esac + done + + LC_COLLATE=$old_lc_collate +} + +filenamelocal=zitadel-${db}.sql +filenamebucket=zitadel-${db}-${name}.sql + +curl -X GET \ + -H "$(oauth2l header --json ${safile} cloud-platform)" \ + -o "${filenamelocal}" \ + "https://storage.googleapis.com/storage/v1/b/${bucket}/o/$(urlencode ${env}/${name}/${filenamebucket})?alt=media" + +/cockroach/cockroach.sh sql --certs-dir=${certs} --host=cockroachdb-public:26257 --database=${db} < ${filenamelocal} diff --git a/build/docker-compose-debug.yml b/build/docker-compose-debug.yml index e212cf4deb..fa29fdcc0e 100644 --- a/build/docker-compose-debug.yml +++ b/build/docker-compose-debug.yml @@ -4,7 +4,7 @@ services: angular: build: context: .. - dockerfile: build/dockerfile + dockerfile: dockerfile target: dev-angular-build args: ENV: dev @@ -14,7 +14,7 @@ services: go: build: context: .. - dockerfile: build/dockerfile + dockerfile: dockerfile target: dev-go-build args: ENV: dev diff --git a/build/docker-compose-dev.yml b/build/docker-compose-dev.yml index da0ec42061..f99a3c2a0a 100644 --- a/build/docker-compose-dev.yml +++ b/build/docker-compose-dev.yml @@ -4,7 +4,7 @@ services: angular: build: context: .. - dockerfile: build/dockerfile + dockerfile: dockerfile target: dev-angular-build args: ENV: dev @@ -14,7 +14,7 @@ services: go: build: context: .. - dockerfile: build/dockerfile + dockerfile: dockerfile target: dev-go-build args: ENV: dev diff --git a/build/dockerfile b/build/dockerfile index 5128278580..038b6e0450 100644 --- a/build/dockerfile +++ b/build/dockerfile @@ -89,7 +89,11 @@ COPY --from=go-base /go/src/github.com/caos/zitadel/pkg/ . ## Go test FROM go-base as go-test COPY . . -RUN go test -race -v -coverprofile=profile.cov ./... +#Migrations for cockroach-secure +RUN go install github.com/rakyll/statik +RUN ./build/operator/prebuild.sh ./migrations + +RUN go test -race -v -coverprofile=profile.cov $(go list ./... | grep -v /operator/) ## Go test FROM scratch as go-codecov @@ -114,16 +118,16 @@ RUN go get github.com/go-delve/delve/cmd/dlv ####################### FROM alpine:latest as artifact RUN adduser -D zitadel -COPY cmd/zitadel/*.yaml / -COPY --from=prod-go-build /go/src/github.com/caos/zitadel/zitadel-linux-amd64 /zitadel -RUN chmod a+x zitadel +COPY cmd/zitadel/*.yaml /app/ +COPY --from=prod-go-build /go/src/github.com/caos/zitadel/zitadel-linux-amd64 /app/zitadel +RUN chmod a+x /app/zitadel RUN ls -la / ## Scratch Image FROM scratch as final COPY --from=artifact /etc/passwd /etc/passwd -## TODO copy should be removed once the operator branch is merged -COPY --from=artifact / / +COPY --from=artifact /etc/ssl/certs /etc/ssl/certs +COPY --from=artifact /app / USER zitadel HEALTHCHECK NONE -ENTRYPOINT ["/zitadel"] \ No newline at end of file +ENTRYPOINT ["/zitadel"] diff --git a/build/operator/.dockerignore b/build/operator/.dockerignore new file mode 100644 index 0000000000..cf9284709f --- /dev/null +++ b/build/operator/.dockerignore @@ -0,0 +1 @@ +**/statik/statik.go \ No newline at end of file diff --git a/build/operator/Dockerfile b/build/operator/Dockerfile new file mode 100644 index 0000000000..cff7f3a223 --- /dev/null +++ b/build/operator/Dockerfile @@ -0,0 +1,59 @@ +####################### +## By default we build the prod enviroment +ARG ENV=prod + +####################### +## Go base build +## Speed up this step by mounting your local go mod pkg directory +####################### +FROM golang:1.15 as go-base + +WORKDIR src/github.com/caos/zitadel/ +COPY go.mod go.sum ./ +RUN go mod download + + +## Go test +FROM go-base as go-test +COPY . . +#Migrations for cockroach-secure +RUN go install github.com/rakyll/statik +RUN ./build/operator/prebuild.sh ./migrations + +RUN go test -race -v -coverprofile=profile.cov ./operator/... + +## Go test +FROM scratch as go-codecov +COPY --from=go-test /go/src/github.com/caos/zitadel/profile.cov profile.cov + +## Go prod build +FROM go-test as prod-go-build + + +ARG ARCH=amd64 +ARG OS=linux +ARG VERSION=none +RUN CGO_ENABLED=0 GOOS=${OS} GOARCH=${ARCH} go build -a -installsuffix cgo -ldflags "-extldflags '-static' -X main.Version=${VERSION}" -o zitadelctl cmd/zitadelctl/main.go + +## Go dev build +FROM go-base as dev-go-build +RUN go get github.com/go-delve/delve/cmd/dlv + +####################### +## Final Production Image +####################### +FROM alpine:latest as artifact +RUN adduser -D zitadel + +ARG ARCH=amd64 +ARG OS=linux +COPY --from=prod-go-build /go/src/github.com/caos/zitadel/zitadelctl /app/zitadelctl +RUN chmod a+x /app/zitadelctl + +## Scratch Image +FROM scratch as final +COPY --from=artifact /etc/passwd /etc/passwd +COPY --from=artifact /app / +USER zitadel +HEALTHCHECK NONE +ENTRYPOINT ["/zitadelctl"] diff --git a/build/operator/prebuild.sh b/build/operator/prebuild.sh new file mode 100755 index 0000000000..b9cb991522 --- /dev/null +++ b/build/operator/prebuild.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +set -e + +statik -src=$1 \ No newline at end of file diff --git a/changelog.config.js b/changelog.config.js new file mode 100644 index 0000000000..e2f2b78884 --- /dev/null +++ b/changelog.config.js @@ -0,0 +1,3 @@ +module.exports = { + "disableEmoji": true +}; diff --git a/cmd/database-debug/main.go b/cmd/database-debug/main.go new file mode 100644 index 0000000000..40cfb3c8c1 --- /dev/null +++ b/cmd/database-debug/main.go @@ -0,0 +1,50 @@ +package main + +import ( + "flag" + "io/ioutil" + + "github.com/caos/orbos/pkg/kubernetes" + + "github.com/caos/zitadel/operator/start" + + "github.com/caos/orbos/mntr" + "github.com/caos/zitadel/operator/helpers" +) + +func main() { + + orbconfig := flag.String("orbconfig", "~/.orb/config", "The orbconfig file to use") + kubeconfig := flag.String("kubeconfig", "~/.kube/config", "The kubeconfig file to use") + verbose := flag.Bool("verbose", false, "Print debug levelled logs") + + flag.Parse() + + monitor := mntr.Monitor{ + OnInfo: mntr.LogMessage, + OnChange: mntr.LogMessage, + OnError: mntr.LogError, + } + + if *verbose { + monitor = monitor.Verbose() + } + + kc, err := ioutil.ReadFile(helpers.PruneHome(*kubeconfig)) + if err != nil { + panic(err) + } + + if err := start.Database( + monitor, + helpers.PruneHome(*orbconfig), + kubernetes.NewK8sClient(monitor, strPtr(string(kc))), + strPtr("database-development"), + ); err != nil { + panic(err) + } +} + +func strPtr(str string) *string { + return &str +} diff --git a/cmd/operator-debug/main.go b/cmd/operator-debug/main.go new file mode 100644 index 0000000000..8a1fb005f6 --- /dev/null +++ b/cmd/operator-debug/main.go @@ -0,0 +1,47 @@ +package main + +import ( + "flag" + "io/ioutil" + + "github.com/caos/orbos/mntr" + "github.com/caos/orbos/pkg/kubernetes" + "github.com/caos/zitadel/operator/helpers" + "github.com/caos/zitadel/operator/start" +) + +func main() { + orbconfig := flag.String("orbconfig", "~/.orb/config", "The orbconfig file to use") + kubeconfig := flag.String("kubeconfig", "~/.kube/config", "The kubeconfig file to use") + verbose := flag.Bool("verbose", false, "Print debug levelled logs") + + flag.Parse() + + monitor := mntr.Monitor{ + OnInfo: mntr.LogMessage, + OnChange: mntr.LogMessage, + OnError: mntr.LogError, + } + + if *verbose { + monitor = monitor.Verbose() + } + + kc, err := ioutil.ReadFile(helpers.PruneHome(*kubeconfig)) + if err != nil { + panic(err) + } + + if err := start.Operator( + monitor, + helpers.PruneHome(*orbconfig), + kubernetes.NewK8sClient(monitor, strPtr(string(kc))), + strPtr("local-debugging"), + ); err != nil { + panic(err) + } +} + +func strPtr(str string) *string { + return &str +} diff --git a/cmd/zitadel/setup.yaml b/cmd/zitadel/setup.yaml index afc1e547c2..8d143838e4 100644 --- a/cmd/zitadel/setup.yaml +++ b/cmd/zitadel/setup.yaml @@ -88,10 +88,94 @@ SetUp: Step6: DefaultLabelPolicy: PrimaryColor: '#222324' - SecondaryColor: '#ffffff' + SecondaryColor: '#ffffff' Step7: OTP: true Step8: U2F: true Step9: - Passwordless: true \ No newline at end of file + Passwordless: true + Step10: + DefaultMailTemplate: + Template: PCFkb2N0eXBlIGh0bWw+CjxodG1sIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiB4bWxuczp2PSJ1cm46c2NoZW1hcy1taWNyb3NvZnQtY29tOnZtbCIgeG1sbnM6bz0idXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6b2ZmaWNlIj4KCjxoZWFkPgogICAgPHRpdGxlPiA8L3RpdGxlPgogICAgPCEtLVtpZiAhbXNvXT48IS0tIC0tPgogICAgPG1ldGEgaHR0cC1lcXVpdj0iWC1VQS1Db21wYXRpYmxlIiBjb250ZW50PSJJRT1lZGdlIj4KICAgIDwhLS08IVtlbmRpZl0tLT4KICAgIDxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04Ij4KICAgIDxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9MSI+CiAgICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgogICAgICAgICNvdXRsb29rIGEgewogICAgICAgICAgICBwYWRkaW5nOiAwOwogICAgICAgIH0KCiAgICAgICAgYm9keSB7CiAgICAgICAgICAgIG1hcmdpbjogMDsKICAgICAgICAgICAgcGFkZGluZzogMDsKICAgICAgICAgICAgLXdlYmtpdC10ZXh0LXNpemUtYWRqdXN0OiAxMDAlOwogICAgICAgICAgICAtbXMtdGV4dC1zaXplLWFkanVzdDogMTAwJTsKICAgICAgICB9CgogICAgICAgIHRhYmxlLAogICAgICAgIHRkIHsKICAgICAgICAgICAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsKICAgICAgICAgICAgbXNvLXRhYmxlLWxzcGFjZTogMHB0OwogICAgICAgICAgICBtc28tdGFibGUtcnNwYWNlOiAwcHQ7CiAgICAgICAgfQoKICAgICAgICBpbWcgewogICAgICAgICAgICBib3JkZXI6IDA7CiAgICAgICAgICAgIGhlaWdodDogYXV0bzsKICAgICAgICAgICAgbGluZS1oZWlnaHQ6IDEwMCU7CiAgICAgICAgICAgIG91dGxpbmU6IG5vbmU7CiAgICAgICAgICAgIHRleHQtZGVjb3JhdGlvbjogbm9uZTsKICAgICAgICAgICAgLW1zLWludGVycG9sYXRpb24tbW9kZTogYmljdWJpYzsKICAgICAgICB9CgogICAgICAgIHAgewogICAgICAgICAgICBkaXNwbGF5OiBibG9jazsKICAgICAgICAgICAgbWFyZ2luOiAxM3B4IDA7CiAgICAgICAgfQogICAgPC9zdHlsZT4KICAgIDwhLS1baWYgbXNvXT4KICAgICAgICAgIDx4bWw+CiAgICAgICAgICA8bzpPZmZpY2VEb2N1bWVudFNldHRpbmdzPgogICAgICAgICAgICA8bzpBbGxvd1BORy8+CiAgICAgICAgICAgIDxvOlBpeGVsc1BlckluY2g+OTY8L286UGl4ZWxzUGVySW5jaD4KICAgICAgICAgIDwvbzpPZmZpY2VEb2N1bWVudFNldHRpbmdzPgogICAgICAgICAgPC94bWw+CiAgICAgICAgICA8IVtlbmRpZl0tLT4KICAgIDwhLS1baWYgbHRlIG1zbyAxMV0+CiAgICAgICAgICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgogICAgICAgICAgICAubWotb3V0bG9vay1ncm91cC1maXggeyB3aWR0aDoxMDAlICFpbXBvcnRhbnQ7IH0KICAgICAgICAgIDwvc3R5bGU+CiAgICAgICAgICA8IVtlbmRpZl0tLT4KICAgIDwhLS1baWYgIW1zb10+PCEtLT4KICAgIDxsaW5rIGhyZWY9Imh0dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzP2ZhbWlseT1MYXRvOjMwMCw0MDAsNTAwLDcwMCIgcmVsPSJzdHlsZXNoZWV0IiB0eXBlPSJ0ZXh0L2NzcyI+CiAgICA8bGluayBocmVmPSJodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tL2Nzcz9mYW1pbHk9VWJ1bnR1OjMwMCw0MDAsNTAwLDcwMCIgcmVsPSJzdHlsZXNoZWV0IiB0eXBlPSJ0ZXh0L2NzcyI+CiAgICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgogICAgICAgIEBpbXBvcnQgdXJsKGh0dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzP2ZhbWlseT1MYXRvOjMwMCw0MDAsNTAwLDcwMCk7CiAgICAgICAgQGltcG9ydCB1cmwoaHR0cHM6Ly9mb250cy5nb29nbGVhcGlzLmNvbS9jc3M/ZmFtaWx5PVVidW50dTozMDAsNDAwLDUwMCw3MDApOwogICAgPC9zdHlsZT4KICAgIDwhLS08IVtlbmRpZl0tLT4KICAgIDxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+CiAgICAgICAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWluLXdpZHRoOjQ4MHB4KSB7CiAgICAgICAgICAgIC5tai1jb2x1bW4tcGVyLTEwMCB7CiAgICAgICAgICAgICAgICB3aWR0aDogMTAwJSAhaW1wb3J0YW50OwogICAgICAgICAgICAgICAgbWF4LXdpZHRoOiAxMDAlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC5tai1jb2x1bW4tcGVyLTIwIHsKICAgICAgICAgICAgICAgIHdpZHRoOiAyMCUgIWltcG9ydGFudDsKICAgICAgICAgICAgICAgIG1heC13aWR0aDogMjAlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC5tai1jb2x1bW4tcGVyLTYwIHsKICAgICAgICAgICAgICAgIHdpZHRoOiA2MCUgIWltcG9ydGFudDsKICAgICAgICAgICAgICAgIG1heC13aWR0aDogNjAlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgPC9zdHlsZT4KICAgIDxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+CiAgICAgICAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOjQ4MHB4KSB7CiAgICAgICAgICAgIHRhYmxlLm1qLWZ1bGwtd2lkdGgtbW9iaWxlIHsKICAgICAgICAgICAgICAgIHdpZHRoOiAxMDAlICFpbXBvcnRhbnQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGQubWotZnVsbC13aWR0aC1tb2JpbGUgewogICAgICAgICAgICAgICAgd2lkdGg6IGF1dG8gIWltcG9ydGFudDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIDwvc3R5bGU+CiAgICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgogICAgICAgIEBtZWRpYSAobWF4LXdpZHRoOjQ4MHB4KSB7CiAgICAgICAgICAgIC5tb2JpbGVfaGlkZGVuIHsKICAgICAgICAgICAgICAgIGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIDwvc3R5bGU+CjwvaGVhZD4KCjxib2R5IHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOnt7LlByaW1hcnlDb2xvcn19OyI+CjxkaXYgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6e3suUHJpbWFyeUNvbG9yfX07Ij4KICAgIDx0YWJsZSBhbGlnbj0iY2VudGVyIiBiYWNrZ3JvdW5kPSJodHRwczovL3N0YXRpYy56aXRhZGVsLmNoL3ppdGFkZWwtbG9nby1vdXRsaW5lLWxpZ2h0LnBuZyIgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiIHJvbGU9InByZXNlbnRhdGlvbiIgc3R5bGU9ImJhY2tncm91bmQ6dXJsKGh0dHBzOi8vc3RhdGljLnppdGFkZWwuY2gveml0YWRlbC1sb2dvLW91dGxpbmUtbGlnaHQucG5nKSBjZW50ZXIgdG9wIC8gYXV0byBuby1yZXBlYXQ7YmFja2dyb3VuZC1wb3NpdGlvbjpjZW50ZXIgdG9wO2JhY2tncm91bmQtcmVwZWF0Om5vLXJlcGVhdDtiYWNrZ3JvdW5kLXNpemU6YXV0bzt3aWR0aDoxMDAlOyI+CiAgICAgICAgPHRib2R5PgogICAgICAgIDx0cj4KICAgICAgICAgICAgPHRkPgogICAgICAgICAgICAgICAgPCEtLVtpZiBtc28gfCBJRV0+CiAgICAgICAgICAgIDx2OnJlY3QgIHN0eWxlPSJtc28td2lkdGgtcGVyY2VudDoxMDAwOyIgeG1sbnM6dj0idXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTp2bWwiIGZpbGw9InRydWUiIHN0cm9rZT0iZmFsc2UiPgogICAgICAgICAgICA8djpmaWxsICBvcmlnaW49IjAuNSwgMCIgcG9zaXRpb249IjAuNSwgMCIgc3JjPSJodHRwczovL3N0YXRpYy56aXRhZGVsLmNoL3ppdGFkZWwtbG9nby1vdXRsaW5lLWxpZ2h0LnBuZyIgdHlwZT0idGlsZSIgLz4KICAgICAgICAgICAgPHY6dGV4dGJveCBzdHlsZT0ibXNvLWZpdC1zaGFwZS10by10ZXh0OnRydWUiIGluc2V0PSIwLDAsMCwwIj4KICAgICAgICAgIDx0YWJsZQogICAgICAgICAgICAgYWxpZ249ImNlbnRlciIgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiIGNsYXNzPSIiIHN0eWxlPSJ3aWR0aDo4MDBweDsiIHdpZHRoPSI4MDAiCiAgICAgICAgICA+CiAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICA8dGQgc3R5bGU9ImxpbmUtaGVpZ2h0OjBweDtmb250LXNpemU6MHB4O21zby1saW5lLWhlaWdodC1ydWxlOmV4YWN0bHk7Ij4KICAgICAgICAgIDwhW2VuZGlmXS0tPgogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0ibWFyZ2luOjBweCBhdXRvO21heC13aWR0aDo4MDBweDsiPgogICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImxpbmUtaGVpZ2h0OjA7Zm9udC1zaXplOjA7Ij4KICAgICAgICAgICAgICAgICAgICAgICAgPHRhYmxlIGFsaWduPSJjZW50ZXIiIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIiByb2xlPSJwcmVzZW50YXRpb24iIHN0eWxlPSJ3aWR0aDoxMDAlOyI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGJvZHk+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPSJib3JkZXI6MDtkaXJlY3Rpb246bHRyO2ZvbnQtc2l6ZTowcHg7cGFkZGluZzoyMHB4IDA7cGFkZGluZy1sZWZ0OjA7dGV4dC1hbGlnbjpjZW50ZXI7Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLVtpZiBtc28gfCBJRV0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0YWJsZSByb2xlPSJwcmVzZW50YXRpb24iIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIj4KICAgICAgICAgICAgICAgICAgICAgICAgPHRyPgogICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPSIiIHdpZHRoPSI4MDBweCIKICAgICAgICAgICAgICAgICAgICAgICAgICA+CiAgICAgICAgICAgICAgICAgICAgICA8IVtlbmRpZl0tLT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRhYmxlIGFsaWduPSJjZW50ZXIiIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIiByb2xlPSJwcmVzZW50YXRpb24iIHN0eWxlPSJ3aWR0aDoxMDAlOyI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGJvZHk+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tW2lmIG1zbyB8IElFXT4KICAgICAgICAgICAgICAgICAgICAgIDx0YWJsZQogICAgICAgICAgICAgICAgICAgICAgICAgYWxpZ249ImNlbnRlciIgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiIGNsYXNzPSIiIHN0eWxlPSJ3aWR0aDo4MDBweDsiIHdpZHRoPSI4MDAiCiAgICAgICAgICAgICAgICAgICAgICA+CiAgICAgICAgICAgICAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9ImxpbmUtaGVpZ2h0OjBweDtmb250LXNpemU6MHB4O21zby1saW5lLWhlaWdodC1ydWxlOmV4YWN0bHk7Ij4KICAgICAgICAgICAgICAgICAgICAgIDwhW2VuZGlmXS0tPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJtYXJnaW46MHB4IGF1dG87bWF4LXdpZHRoOjgwMHB4OyI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGFibGUgYWxpZ249ImNlbnRlciIgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiIHJvbGU9InByZXNlbnRhdGlvbiIgc3R5bGU9IndpZHRoOjEwMCU7Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGJvZHk+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9ImRpcmVjdGlvbjpsdHI7Zm9udC1zaXplOjBweDtwYWRkaW5nOjA7dGV4dC1hbGlnbjpjZW50ZXI7Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS1baWYgbXNvIHwgSUVdPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRhYmxlIHJvbGU9InByZXNlbnRhdGlvbiIgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPSIiIHN0eWxlPSJ3aWR0aDo4MDBweDsiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCFbZW5kaWZdLS0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJtai1jb2x1bW4tcGVyLTEwMCBtai1vdXRsb29rLWdyb3VwLWZpeCIgc3R5bGU9ImZvbnQtc2l6ZTowO2xpbmUtaGVpZ2h0OjA7dGV4dC1hbGlnbjpsZWZ0O2Rpc3BsYXk6aW5saW5lLWJsb2NrO3dpZHRoOjEwMCU7ZGlyZWN0aW9uOmx0cjsiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS1baWYgbXNvIHwgSUVdPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0YWJsZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIiByb2xlPSJwcmVzZW50YXRpb24iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlPSJ2ZXJ0aWNhbC1hbGlnbjp0b3A7d2lkdGg6ODAwcHg7IgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IVtlbmRpZl0tLT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJtai1jb2x1bW4tcGVyLTEwMCBtai1vdXRsb29rLWdyb3VwLWZpeCIgc3R5bGU9ImZvbnQtc2l6ZTowcHg7dGV4dC1hbGlnbjpsZWZ0O2RpcmVjdGlvbjpsdHI7ZGlzcGxheTppbmxpbmUtYmxvY2s7dmVydGljYWwtYWxpZ246dG9wO3dpZHRoOjEwMCU7Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRhYmxlIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIiByb2xlPSJwcmVzZW50YXRpb24iIHdpZHRoPSIxMDAlIj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0Ym9keT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9InZlcnRpY2FsLWFsaWduOnRvcDtwYWRkaW5nOjA7Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRhYmxlIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIiByb2xlPSJwcmVzZW50YXRpb24iIHN0eWxlPSIiIHdpZHRoPSIxMDAlIj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgYWxpZ249ImxlZnQiIHN0eWxlPSJmb250LXNpemU6MHB4O3BhZGRpbmc6MjBweCAwIDUwcHggMjBweDt3b3JkLWJyZWFrOmJyZWFrLXdvcmQ7Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRhYmxlIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIiByb2xlPSJwcmVzZW50YXRpb24iIHN0eWxlPSJib3JkZXItY29sbGFwc2U6Y29sbGFwc2U7Ym9yZGVyLXNwYWNpbmc6MHB4OyI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGJvZHk+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPSJ3aWR0aDoxNTBweDsiPiA8aW1nIGhlaWdodD0iYXV0byIgc3JjPSJodHRwczovL3N0YXRpYy56aXRhZGVsLmNoL3ppdGFkZWwtbG9nby1saWdodC5wbmciIHN0eWxlPSJib3JkZXI6MDtkaXNwbGF5OmJsb2NrO291dGxpbmU6bm9uZTt0ZXh0LWRlY29yYXRpb246bm9uZTtoZWlnaHQ6YXV0bzt3aWR0aDoxMDAlO2ZvbnQtc2l6ZToxM3B4OyIgd2lkdGg9IjE1MCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLz4gPC90ZD4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RhYmxlPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RhYmxlPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90Ym9keT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90YWJsZT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tW2lmIG1zbyB8IElFXT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCFbZW5kaWZdLS0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS1baWYgbXNvIHwgSUVdPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCFbZW5kaWZdLS0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90YWJsZT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS1baWYgbXNvIHwgSUVdPgogICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgICAgICAgICAgICA8L3RhYmxlPgogICAgICAgICAgICAgICAgICAgICAgPCFbZW5kaWZdLS0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RhYmxlPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tW2lmIG1zbyB8IElFXT4KICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgICAgICAgICAgICA8L3RyPgogICAgICAgICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9IiIgd2lkdGg9IjgwMHB4IgogICAgICAgICAgICAgICAgICAgICAgICAgID4KICAgICAgICAgICAgICAgICAgICAgIDwhW2VuZGlmXS0tPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGFibGUgYWxpZ249ImNlbnRlciIgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiIHJvbGU9InByZXNlbnRhdGlvbiIgc3R5bGU9IndpZHRoOjEwMCU7Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0Ym9keT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQ+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS1baWYgbXNvIHwgSUVdPgogICAgICAgICAgICAgICAgICAgICAgPHRhYmxlCiAgICAgICAgICAgICAgICAgICAgICAgICBhbGlnbj0iY2VudGVyIiBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCIgY2xhc3M9IiIgc3R5bGU9IndpZHRoOjgwMHB4OyIgd2lkdGg9IjgwMCIKICAgICAgICAgICAgICAgICAgICAgID4KICAgICAgICAgICAgICAgICAgICAgICAgPHRyPgogICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT0ibGluZS1oZWlnaHQ6MHB4O2ZvbnQtc2l6ZTowcHg7bXNvLWxpbmUtaGVpZ2h0LXJ1bGU6ZXhhY3RseTsiPgogICAgICAgICAgICAgICAgICAgICAgPCFbZW5kaWZdLS0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9Im1hcmdpbjowcHggYXV0bzttYXgtd2lkdGg6ODAwcHg7Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0YWJsZSBhbGlnbj0iY2VudGVyIiBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCIgcm9sZT0icHJlc2VudGF0aW9uIiBzdHlsZT0id2lkdGg6MTAwJTsiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0Ym9keT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT0iZGlyZWN0aW9uOmx0cjtmb250LXNpemU6MHB4O3BhZGRpbmc6MDt0ZXh0LWFsaWduOmNlbnRlcjsiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLVtpZiBtc28gfCBJRV0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGFibGUgcm9sZT0icHJlc2VudGF0aW9uIiBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9Im1vYmlsZV9oaWRkZW4tb3V0bG9vayIgc3R5bGU9InZlcnRpY2FsLWFsaWduOnRvcDt3aWR0aDoxNjBweDsiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCFbZW5kaWZdLS0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJtai1jb2x1bW4tcGVyLTIwIG1qLW91dGxvb2stZ3JvdXAtZml4IG1vYmlsZV9oaWRkZW4iIHN0eWxlPSJmb250LXNpemU6MHB4O3RleHQtYWxpZ246bGVmdDtkaXJlY3Rpb246bHRyO2Rpc3BsYXk6aW5saW5lLWJsb2NrO3ZlcnRpY2FsLWFsaWduOnRvcDt3aWR0aDoxMDAlOyI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRhYmxlIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIiByb2xlPSJwcmVzZW50YXRpb24iIHdpZHRoPSIxMDAlIj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRib2R5PgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9InZlcnRpY2FsLWFsaWduOnRvcDtwYWRkaW5nOjA7Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGFibGUgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiIHJvbGU9InByZXNlbnRhdGlvbiIgc3R5bGU9IiIgd2lkdGg9IjEwMCUiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgYWxpZ249ImxlZnQiIHN0eWxlPSJmb250LXNpemU6MHB4O3BhZGRpbmc6MDt3b3JkLWJyZWFrOmJyZWFrLXdvcmQ7Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGFibGUgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiIHJvbGU9InByZXNlbnRhdGlvbiIgc3R5bGU9ImJvcmRlci1jb2xsYXBzZTpjb2xsYXBzZTtib3JkZXItc3BhY2luZzowcHg7Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRib2R5PgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9IndpZHRoOjgwcHg7Ij4gPGltZyBoZWlnaHQ9IjEwMCIgc3JjPSJodHRwczovL3N0YXRpYy56aXRhZGVsLmNoL2ZsYXZvci1zcGlrZXMtc21hbGwtb3BhY2l0eTQwLnBuZyIgc3R5bGU9ImJvcmRlcjowO2Rpc3BsYXk6YmxvY2s7b3V0bGluZTpub25lO3RleHQtZGVjb3JhdGlvbjpub25lO2hlaWdodDoxMDAlO3dpZHRoOjEwMCU7Zm9udC1zaXplOjEzcHg7IgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg9IjgwIiAvPiA8L3RkPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS1baWYgbXNvIHwgSUVdPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9IiIgc3R5bGU9InZlcnRpY2FsLWFsaWduOnRvcDt3aWR0aDo0ODBweDsiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCFbZW5kaWZdLS0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJtai1jb2x1bW4tcGVyLTYwIG1qLW91dGxvb2stZ3JvdXAtZml4IiBzdHlsZT0iZm9udC1zaXplOjBweDt0ZXh0LWFsaWduOmxlZnQ7ZGlyZWN0aW9uOmx0cjtkaXNwbGF5OmlubGluZS1ibG9jazt2ZXJ0aWNhbC1hbGlnbjp0b3A7d2lkdGg6MTAwJTsiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0YWJsZSBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCIgcm9sZT0icHJlc2VudGF0aW9uIiB3aWR0aD0iMTAwJSI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0Ym9keT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPSJ2ZXJ0aWNhbC1hbGlnbjp0b3A7cGFkZGluZzowOyI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRhYmxlIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIiByb2xlPSJwcmVzZW50YXRpb24iIHN0eWxlPSIiIHdpZHRoPSIxMDAlIj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGFsaWduPSJjZW50ZXIiIHN0eWxlPSJmb250LXNpemU6MHB4O3BhZGRpbmc6MTBweCAyNXB4O3dvcmQtYnJlYWs6YnJlYWstd29yZDsiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImZvbnQtZmFtaWx5OkxhdG8sIEFyaWFsLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWY7Zm9udC1zaXplOjJyZW07Zm9udC13ZWlnaHQ6MjAwO2xpbmUtaGVpZ2h0OjE7dGV4dC1hbGlnbjpjZW50ZXI7Y29sb3I6e3suU2Vjb25kYXJ5Q29sb3J9fTsiPnt7LkdyZWV0aW5nfX08L2Rpdj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBhbGlnbj0iY2VudGVyIiBzdHlsZT0iZm9udC1zaXplOjBweDtwYWRkaW5nOjEwcHggMjVweDt3b3JkLWJyZWFrOmJyZWFrLXdvcmQ7Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJmb250LWZhbWlseTpMYXRvLCBBcmlhbCwgSGVsdmV0aWNhLCBzYW5zLXNlcmlmO2ZvbnQtc2l6ZToxcmVtO2ZvbnQtd2VpZ2h0OmxpZ2h0O2xpbmUtaGVpZ2h0OjEuNTt0ZXh0LWFsaWduOmNlbnRlcjtjb2xvcjp7ey5TZWNvbmRhcnlDb2xvcn19OyI+e3suVGV4dH19PC9kaXY+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgYWxpZ249ImNlbnRlciIgdmVydGljYWwtYWxpZ249Im1pZGRsZSIgc3R5bGU9ImZvbnQtc2l6ZTowcHg7cGFkZGluZzoxMHB4IDI1cHg7d29yZC1icmVhazpicmVhay13b3JkOyI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRhYmxlIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIiByb2xlPSJwcmVzZW50YXRpb24iIHN0eWxlPSJib3JkZXItY29sbGFwc2U6c2VwYXJhdGU7bGluZS1oZWlnaHQ6MTAwJTsiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgYWxpZ249ImNlbnRlciIgYmdjb2xvcj0iIzUyODJDMSIgcm9sZT0icHJlc2VudGF0aW9uIiBzdHlsZT0iYm9yZGVyOm5vbmU7Ym9yZGVyLXJhZGl1czozcHg7Y3Vyc29yOmF1dG87bXNvLXBhZGRpbmctYWx0OjEwcHggMjVweDtiYWNrZ3JvdW5kOiM1MjgyQzE7IiB2YWxpZ249Im1pZGRsZSI+IDxhIGhyZWY9Int7LlVSTH19IiBzdHlsZT0iZGlzcGxheTppbmxpbmUtYmxvY2s7YmFja2dyb3VuZDojNTI4MkMxO2NvbG9yOiNmZmZmZmY7Zm9udC1mYW1pbHk6VWJ1bnR1LCBIZWx2ZXRpY2EsIEFyaWFsLCBzYW5zLXNlcmlmO2ZvbnQtc2l6ZToxNnB4O2ZvbnQtd2VpZ2h0Om5vcm1hbDtsaW5lLWhlaWdodDoxMjAlO21hcmdpbjowO3RleHQtZGVjb3JhdGlvbjpub25lO3RleHQtdHJhbnNmb3JtOm5vbmU7cGFkZGluZzoxMHB4IDI1cHg7bXNvLXBhZGRpbmctYWx0OjBweDtib3JkZXItcmFkaXVzOjNweDsiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldD0iX2JsYW5rIj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3suQnV0dG9uVGV4dH19CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPiA8L3RkPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgYWxpZ249ImNlbnRlciIgc3R5bGU9ImZvbnQtc2l6ZTowcHg7cGFkZGluZzozMHB4IDA7d29yZC1icmVhazpicmVhay13b3JkOyI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iZm9udC1mYW1pbHk6TGF0bywgQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZjtmb250LXNpemU6MTNweDtsaW5lLWhlaWdodDoxO3RleHQtYWxpZ246Y2VudGVyO2NvbG9yOnt7LlNlY29uZGFyeUNvbG9yfX07Ij48YSBocmVmPSJodHRwOi8vd3d3LmNhb3MuY2giIHN0eWxlPSJjb2xvcjojZTkxZTYzOyB0ZXh0LWRlY29yYXRpb246IG5vbmU7IiB0YXJnZXQ9Il9ibGFuayI+IENBT1MgQUcgPC9hPiB8IFRldWZlbmVyIFN0cmFzc2UgMTkgfCBDSC05MDAwIFN0LiBHYWxsZW48L2Rpdj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90YWJsZT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGJvZHk+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90YWJsZT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLVtpZiBtc28gfCBJRV0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz0ibW9iaWxlX2hpZGRlbi1vdXRsb29rIiBzdHlsZT0idmVydGljYWwtYWxpZ246dG9wO3dpZHRoOjE2MHB4OyIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IVtlbmRpZl0tLT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9Im1qLWNvbHVtbi1wZXItMjAgbWotb3V0bG9vay1ncm91cC1maXggbW9iaWxlX2hpZGRlbiIgc3R5bGU9ImZvbnQtc2l6ZTowcHg7dGV4dC1hbGlnbjpsZWZ0O2RpcmVjdGlvbjpsdHI7ZGlzcGxheTppbmxpbmUtYmxvY2s7dmVydGljYWwtYWxpZ246dG9wO3dpZHRoOjEwMCU7Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGFibGUgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiIHJvbGU9InByZXNlbnRhdGlvbiIgd2lkdGg9IjEwMCUiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGJvZHk+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBzdHlsZT0idmVydGljYWwtYWxpZ246dG9wO3BhZGRpbmc6MDsiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0YWJsZSBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCIgcm9sZT0icHJlc2VudGF0aW9uIiBzdHlsZT0iIiB3aWR0aD0iMTAwJSI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBhbGlnbj0icmlnaHQiIHN0eWxlPSJmb250LXNpemU6MHB4O3BhZGRpbmc6MDt3b3JkLWJyZWFrOmJyZWFrLXdvcmQ7Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGFibGUgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiIHJvbGU9InByZXNlbnRhdGlvbiIgc3R5bGU9ImJvcmRlci1jb2xsYXBzZTpjb2xsYXBzZTtib3JkZXItc3BhY2luZzowcHg7Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRib2R5PgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9IndpZHRoOjE2MHB4OyI+IDxpbWcgaGVpZ2h0PSJhdXRvIiBzcmM9Imh0dHBzOi8vc3RhdGljLnppdGFkZWwuY2gvZmxhdm9yLXNwaWtlcy1iaWctb3BhY2l0eTQwLnBuZyIgc3R5bGU9ImJvcmRlcjowO2Rpc3BsYXk6YmxvY2s7b3V0bGluZTpub25lO3RleHQtZGVjb3JhdGlvbjpub25lO2hlaWdodDphdXRvO3dpZHRoOjEwMCU7Zm9udC1zaXplOjEzcHg7IgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoPSIxNjAiIC8+IDwvdGQ+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGJvZHk+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90YWJsZT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90YWJsZT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGJvZHk+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90YWJsZT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLVtpZiBtc28gfCBJRV0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90YWJsZT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IVtlbmRpZl0tLT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGJvZHk+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RhYmxlPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLVtpZiBtc28gfCBJRV0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD4KICAgICAgICAgICAgICAgICAgICAgICAgPC90cj4KICAgICAgICAgICAgICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgICAgICAgICAgICAgICA8IVtlbmRpZl0tLT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGJvZHk+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS1baWYgbXNvIHwgSUVdPgogICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgICAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz0iIiB3aWR0aD0iODAwcHgiCiAgICAgICAgICAgICAgICAgICAgICAgICAgPgogICAgICAgICAgICAgICAgICAgICAgPCFbZW5kaWZdLS0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0YWJsZSBhbGlnbj0iY2VudGVyIiBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCIgcm9sZT0icHJlc2VudGF0aW9uIiBzdHlsZT0id2lkdGg6MTAwJTsiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRib2R5PgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLVtpZiBtc28gfCBJRV0+CiAgICAgICAgICAgICAgICAgICAgICA8dGFibGUKICAgICAgICAgICAgICAgICAgICAgICAgIGFsaWduPSJjZW50ZXIiIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIiBjbGFzcz0iIiBzdHlsZT0id2lkdGg6ODAwcHg7IiB3aWR0aD0iODAwIgogICAgICAgICAgICAgICAgICAgICAgPgogICAgICAgICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPSJsaW5lLWhlaWdodDowcHg7Zm9udC1zaXplOjBweDttc28tbGluZS1oZWlnaHQtcnVsZTpleGFjdGx5OyI+CiAgICAgICAgICAgICAgICAgICAgICA8IVtlbmRpZl0tLT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0ibWFyZ2luOjBweCBhdXRvO21heC13aWR0aDo4MDBweDsiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRhYmxlIGFsaWduPSJjZW50ZXIiIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIiByb2xlPSJwcmVzZW50YXRpb24iIHN0eWxlPSJ3aWR0aDoxMDAlOyI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRib2R5PgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPSJkaXJlY3Rpb246bHRyO2ZvbnQtc2l6ZTowcHg7cGFkZGluZzowO3RleHQtYWxpZ246Y2VudGVyOyI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tW2lmIG1zbyB8IElFXT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0YWJsZSByb2xlPSJwcmVzZW50YXRpb24iIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz0iIiBzdHlsZT0id2lkdGg6ODAwcHg7IgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhW2VuZGlmXS0tPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz0ibWotY29sdW1uLXBlci0xMDAgbWotb3V0bG9vay1ncm91cC1maXgiIHN0eWxlPSJmb250LXNpemU6MDtsaW5lLWhlaWdodDowO3RleHQtYWxpZ246bGVmdDtkaXNwbGF5OmlubGluZS1ibG9jazt3aWR0aDoxMDAlO2RpcmVjdGlvbjpsdHI7Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tW2lmIG1zbyB8IElFXT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGFibGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCIgcm9sZT0icHJlc2VudGF0aW9uIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZT0idmVydGljYWwtYWxpZ246dG9wO3dpZHRoOjgwMHB4OyIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCFbZW5kaWZdLS0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz0ibWotY29sdW1uLXBlci0xMDAgbWotb3V0bG9vay1ncm91cC1maXgiIHN0eWxlPSJmb250LXNpemU6MHB4O3RleHQtYWxpZ246bGVmdDtkaXJlY3Rpb246bHRyO2Rpc3BsYXk6aW5saW5lLWJsb2NrO3ZlcnRpY2FsLWFsaWduOnRvcDt3aWR0aDoxMDAlOyI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0YWJsZSBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCIgcm9sZT0icHJlc2VudGF0aW9uIiB3aWR0aD0iMTAwJSI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGJvZHk+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIHN0eWxlPSJ2ZXJ0aWNhbC1hbGlnbjp0b3A7cGFkZGluZzoyMHB4OyI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0YWJsZSBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCIgcm9sZT0icHJlc2VudGF0aW9uIiBzdHlsZT0iIiB3aWR0aD0iMTAwJSI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGFsaWduPSJyaWdodCIgc3R5bGU9ImZvbnQtc2l6ZTowcHg7cGFkZGluZzowO3dvcmQtYnJlYWs6YnJlYWstd29yZDsiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGFibGUgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiIHJvbGU9InByZXNlbnRhdGlvbiIgc3R5bGU9ImJvcmRlci1jb2xsYXBzZTpjb2xsYXBzZTtib3JkZXItc3BhY2luZzowcHg7Ij4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0Ym9keT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9IndpZHRoOjY1cHg7Ij4gPGltZyBoZWlnaHQ9ImF1dG8iIHNyYz0iaHR0cHM6Ly9zdGF0aWMueml0YWRlbC5jaC9sb2dvX3doaXRlZm9udF90cmFuc3BhcmVudGJnLnBuZyIgc3R5bGU9ImJvcmRlcjowO2Rpc3BsYXk6YmxvY2s7b3V0bGluZTpub25lO3RleHQtZGVjb3JhdGlvbjpub25lO2hlaWdodDphdXRvO3dpZHRoOjEwMCU7Zm9udC1zaXplOjEzcHg7IgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoPSI2NSIgLz4gPC90ZD4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RhYmxlPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RhYmxlPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90Ym9keT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90YWJsZT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tW2lmIG1zbyB8IElFXT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCFbZW5kaWZdLS0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS1baWYgbXNvIHwgSUVdPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCFbZW5kaWZdLS0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90cj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90YWJsZT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS1baWYgbXNvIHwgSUVdPgogICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgICAgICAgICAgICA8L3RhYmxlPgogICAgICAgICAgICAgICAgICAgICAgPCFbZW5kaWZdLS0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RhYmxlPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tW2lmIG1zbyB8IElFXT4KICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgICAgICAgICAgICA8L3RyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RhYmxlPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgPCFbZW5kaWZdLS0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PgogICAgICAgICAgICAgICAgICAgICAgICA8L3RhYmxlPgogICAgICAgICAgICAgICAgICAgIDwvZGl2PgogICAgICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICAgICAgICA8IS0tW2lmIG1zbyB8IElFXT4KICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICA8L3RyPgogICAgICAgICAgPC90YWJsZT4KICAgICAgICAgICAgPC92OnRleHRib3g+CiAgICAgICAgICA8L3Y6cmVjdD4KICAgICAgICA8IVtlbmRpZl0tLT4KICAgICAgICAgICAgPC90ZD4KICAgICAgICA8L3RyPgogICAgICAgIDwvdGJvZHk+CiAgICA8L3RhYmxlPgo8L2Rpdj4KPC9ib2R5PgoKPC9odG1sPg== + DefaultMailTexts: + - MailTextType: InitCode + Language: DE + Title: Zitadel - User initialisieren + PreHeader: User initialisieren + Subject: User initialisieren + Greeting: Hallo {{.FirstName}} {{.LastName}}, + Text: Dieser Benutzer wurde soeben im Zitadel erstellt. Mit dem Benutzernamen <br><strong>{{.PreferredLoginName}}</strong><br> kannst du dich anmelden. Nutze den untenstehenden Button, um die Initialisierung abzuschliessen <br>(Code <strong>{{.Code}}</strong>).<br> Falls du dieses Mail nicht angefordert hast, kannst du es einfach ignorieren. + ButtonText: Initialisierung abschliessen + - MailTextType: PasswordReset + Language: DE + Title: Zitadel - Passwort zurücksetzen + PreHeader: Passwort zurücksetzen + Subject: Passwort zurücksetzen + Greeting: Hallo {{.FirstName}} {{.LastName}}, + Text: Wir haben eine Anfrage für das Zurücksetzen deines Passwortes bekommen. Du kannst den untenstehenden Button verwenden, um dein Passwort zurückzusetzen <br>(Code <strong>{{.Code}}</strong>).<br> Falls du dieses Mail nicht angefordert hast, kannst du es ignorieren. + ButtonText: Passwort zurücksetzen + - MailTextType: VerifyEmail + Language: DE + Title: Zitadel - Email verifizieren + PreHeader: Email verifizieren + Subject: Email verifizieren + Greeting: Hallo {{.FirstName}} {{.LastName}}, + Text: Eine neue E-Mail Adresse wurde hinzugefügt. Bitte verwende den untenstehenden Button um diese zu verifizieren <br>(Code <strong>{{.Code}}</strong>).<br> Falls du deine E-Mail Adresse nicht selber hinzugefügt hast, kannst du dieses E-Mail ignorieren. + ButtonText: Email verifizieren + - MailTextType: VerifyPhone + Language: DE + Title: Zitadel - Telefonnummer verifizieren + PreHeader: Telefonnummer verifizieren + Subject: Telefonnummer verifizieren + Greeting: Hallo {{.FirstName}} {{.LastName}}, + Text: Eine Telefonnummer wurde hinzugefügt. Bitte verifiziere diese in dem du folgenden Code eingibst<br>(Code <strong>{{.Code}}</strong>).<br> + ButtonText: Telefon verifizieren + - MailTextType: DomainClaimed + Language: DE + Title: Zitadel - Domain wurde beansprucht + PreHeader: Email / Username ändern + Subject: Domain wurde beansprucht + Greeting: Hallo {{.FirstName}} {{.LastName}}, + Text: Die Domain {{.Domain}} wurde von einer Organisation beansprucht. Dein derzeitiger User {{.Username}} ist nicht Teil dieser Organisation. Daher musst du beim nächsten Login eine neue Email hinterlegen. Für diesen Login haben wir dir einen temporären Usernamen ({{.TempUsername}}) erstellt. + ButtonText: Login + - MailTextType: InitCode + Language: EN + Title: Zitadel - Initialize User + PreHeader: Initialize User + Subject: Initialize User + Greeting: Hello {{.FirstName}} {{.LastName}}, + Text: This user was created in Zitadel. Use the username {{.PreferredLoginName}} to login. Please click the button below to finish the initialization process. (Code {{.Code}}) If you didn't ask for this mail, please ignore it. + ButtonText: Finish initialization + - MailTextType: PasswordReset + Language: EN + Title: Zitadel - Reset password + PreHeader: Reset password + Subject: Reset password + Greeting: Hello {{.FirstName}} {{.LastName}}, + Text: We received a password reset request. Please use the button below to reset your password. (Code {{.Code}}) If you didn't ask for this mail, please ignore it. + ButtonText: Reset password + - MailTextType: VerifyEmail + Language: EN + Title: Zitadel - Verify email + PreHeader: Verify email + Subject: Verify email + Greeting: Hello {{.FirstName}} {{.LastName}}, + Text: A new email has been added. Please use the button below to verify your mail. (Code {{.Code}}) If you din't add a new email, please ignore this email. + ButtonText: Verify email + - MailTextType: VerifyPhone + Language: EN + Title: Zitadel - Verify phone + PreHeader: Verify phone + Subject: Verify phone + Greeting: Hello {{.FirstName}} {{.LastName}}, + Text: A new phonenumber has been added. Please use the following code to verify it {{.Code}}. + ButtonText: Verify phone + - MailTextType: DomainClaimed + Language: EN + Title: Zitadel - Domain has been claimed + PreHeader: Change email / username + Subject: Domain has been claimed + Greeting: Hello {{.FirstName}} {{.LastName}}, + 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 diff --git a/cmd/zitadel/system-defaults.yaml b/cmd/zitadel/system-defaults.yaml index 1f22bf6185..cd84668dce 100644 --- a/cmd/zitadel/system-defaults.yaml +++ b/cmd/zitadel/system-defaults.yaml @@ -1,5 +1,5 @@ SystemDefaults: - DefaultLanguage: 'de' + DefaultLanguage: 'en' Domain: $ZITADEL_DEFAULT_DOMAIN ZitadelDocs: Issuer: $ZITADEL_ISSUER diff --git a/cmd/zitadelctl/cmds/backup.go b/cmd/zitadelctl/cmds/backup.go new file mode 100644 index 0000000000..d00ec60046 --- /dev/null +++ b/cmd/zitadelctl/cmds/backup.go @@ -0,0 +1,73 @@ +package cmds + +import ( + "github.com/caos/orbos/pkg/kubernetes" + "github.com/caos/zitadel/operator/api" + "github.com/caos/zitadel/operator/start" + "github.com/spf13/cobra" + "io/ioutil" +) + +func BackupCommand(rv RootValues) *cobra.Command { + var ( + kubeconfig string + backup string + cmd = &cobra.Command{ + Use: "backup", + Short: "Instant backup", + Long: "Instant backup", + } + ) + + flags := cmd.Flags() + flags.StringVar(&kubeconfig, "kubeconfig", "~/.kube/config", "Kubeconfig of cluster where the backup should be done") + flags.StringVar(&backup, "backup", "", "Name used for backup folder") + + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { + _, monitor, orbConfig, gitClient, version, errFunc, err := rv() + if err != nil { + return err + } + defer func() { + err = errFunc(err) + }() + + if err := gitClient.Configure(orbConfig.URL, []byte(orbConfig.Repokey)); err != nil { + return err + } + + if err := gitClient.Clone(); err != nil { + return err + } + + found, err := api.ExistsDatabaseYml(gitClient) + if err != nil { + return err + } + if found { + + value, err := ioutil.ReadFile(kubeconfig) + if err != nil { + monitor.Error(err) + return nil + } + kubeconfigStr := string(value) + + k8sClient := kubernetes.NewK8sClient(monitor, &kubeconfigStr) + if k8sClient.Available() { + if err := start.Backup( + monitor, + orbConfig.Path, + k8sClient, + backup, + &version, + ); err != nil { + return err + } + } + + } + return nil + } + return cmd +} diff --git a/cmd/zitadelctl/cmds/backuplist.go b/cmd/zitadelctl/cmds/backuplist.go new file mode 100644 index 0000000000..dbf356a352 --- /dev/null +++ b/cmd/zitadelctl/cmds/backuplist.go @@ -0,0 +1,54 @@ +package cmds + +import ( + "fmt" + "sort" + + "github.com/caos/zitadel/pkg/databases" + "github.com/spf13/cobra" +) + +func BackupListCommand(rv RootValues) *cobra.Command { + var ( + cmd = &cobra.Command{ + Use: "backuplist", + Short: "Get a list of all backups", + Long: "Get a list of all backups", + } + ) + + cmd.RunE = func(cmd *cobra.Command, args []string) error { + _, monitor, orbConfig, gitClient, _, errFunc, err := rv() + if err != nil { + return err + } + defer func() { + err = errFunc(err) + }() + + if err := gitClient.Configure(orbConfig.URL, []byte(orbConfig.Repokey)); err != nil { + monitor.Error(err) + return nil + } + + if err := gitClient.Clone(); err != nil { + monitor.Error(err) + return nil + } + + backups, err := databases.ListBackups(monitor, gitClient) + if err != nil { + monitor.Error(err) + return nil + } + + sort.Slice(backups, func(i, j int) bool { + return backups[i] > backups[j] + }) + for _, backup := range backups { + fmt.Println(backup) + } + return nil + } + return cmd +} diff --git a/cmd/zitadelctl/cmds/readsecret.go b/cmd/zitadelctl/cmds/readsecret.go new file mode 100644 index 0000000000..3a0d9937cb --- /dev/null +++ b/cmd/zitadelctl/cmds/readsecret.go @@ -0,0 +1,57 @@ +package cmds + +import ( + "os" + + "github.com/caos/orbos/pkg/secret" + "github.com/caos/zitadel/operator/secrets" + "github.com/spf13/cobra" +) + +func ReadSecretCommand(rv RootValues) *cobra.Command { + return &cobra.Command{ + Use: "readsecret [path]", + Short: "Print a secrets decrypted value to stdout", + Long: "Print a secrets decrypted value to stdout.\nIf no path is provided, a secret can interactively be chosen from a list of all possible secrets", + Args: cobra.MaximumNArgs(1), + Example: `zitadelctl readsecret zitadel.emailappkey > ~/emailappkey`, + RunE: func(cmd *cobra.Command, args []string) error { + + _, monitor, orbConfig, gitClient, _, errFunc, err := rv() + if err != nil { + return err + } + defer func() { + err = errFunc(err) + }() + if err := gitClient.Configure(orbConfig.URL, []byte(orbConfig.Repokey)); err != nil { + return err + } + + if err := gitClient.Clone(); err != nil { + return err + } + + path := "" + if len(args) > 0 { + path = args[0] + } + + value, err := secret.Read( + monitor, + gitClient, + path, + secrets.GetAllSecretsFunc(orbConfig)) + if err != nil { + monitor.Error(err) + return nil + } + + if _, err := os.Stdout.Write([]byte(value)); err != nil { + monitor.Error(err) + return nil + } + return nil + }, + } +} diff --git a/cmd/zitadelctl/cmds/restore.go b/cmd/zitadelctl/cmds/restore.go new file mode 100644 index 0000000000..a9230d6202 --- /dev/null +++ b/cmd/zitadelctl/cmds/restore.go @@ -0,0 +1,100 @@ +package cmds + +import ( + "errors" + "io/ioutil" + + "github.com/caos/zitadel/operator/helpers" + + "github.com/caos/orbos/pkg/kubernetes" + "github.com/caos/zitadel/operator/start" + "github.com/caos/zitadel/pkg/databases" + "github.com/manifoldco/promptui" + "github.com/spf13/cobra" +) + +func RestoreCommand(rv RootValues) *cobra.Command { + var ( + backup string + kubeconfig string + cmd = &cobra.Command{ + Use: "restore", + Short: "Restore from backup", + Long: "Restore from backup", + } + ) + + flags := cmd.Flags() + flags.StringVar(&backup, "backup", "", "Backup used for db restore") + flags.StringVar(&kubeconfig, "kubeconfig", "~/.kube/config", "Kubeconfig for ZITADEL operator deployment") + + cmd.RunE = func(cmd *cobra.Command, args []string) error { + _, monitor, orbConfig, gitClient, version, errFunc, err := rv() + if err != nil { + return err + } + defer func() { + err = errFunc(err) + }() + + kubeconfig = helpers.PruneHome(kubeconfig) + + if err := gitClient.Configure(orbConfig.URL, []byte(orbConfig.Repokey)); err != nil { + monitor.Error(err) + return nil + } + + if err := gitClient.Clone(); err != nil { + monitor.Error(err) + return nil + } + + value, err := ioutil.ReadFile(kubeconfig) + if err != nil { + monitor.Error(err) + return nil + } + kubeconfigStr := string(value) + + k8sClient := kubernetes.NewK8sClient(monitor, &kubeconfigStr) + if k8sClient.Available() { + list, err := databases.ListBackups(monitor, gitClient) + if err != nil { + monitor.Error(err) + return nil + } + + if backup == "" { + prompt := promptui.Select{ + Label: "Select backup to restore", + Items: list, + } + + _, result, err := prompt.Run() + if err != nil { + monitor.Error(err) + return nil + } + backup = result + } + existing := false + for _, listedBackup := range list { + if listedBackup == backup { + existing = true + } + } + + if !existing { + monitor.Error(errors.New("chosen backup is not existing")) + return nil + } + + if err := start.Restore(monitor, gitClient, orbConfig, k8sClient, backup, &version); err != nil { + monitor.Error(err) + } + return nil + } + return nil + } + return cmd +} diff --git a/cmd/zitadelctl/cmds/root.go b/cmd/zitadelctl/cmds/root.go new file mode 100644 index 0000000000..1568d40ca9 --- /dev/null +++ b/cmd/zitadelctl/cmds/root.go @@ -0,0 +1,72 @@ +package cmds + +import ( + "context" + "github.com/caos/orbos/mntr" + "github.com/caos/orbos/pkg/git" + "github.com/caos/orbos/pkg/orb" + "github.com/caos/zitadel/operator/helpers" + "github.com/spf13/cobra" +) + +type RootValues func() (context.Context, mntr.Monitor, *orb.Orb, *git.Client, string, errFunc, error) + +type errFunc func(err error) error + +func RootCommand(version string) (*cobra.Command, RootValues) { + + var ( + verbose bool + orbConfigPath string + ) + + cmd := &cobra.Command{ + Use: "zitadelctl [flags]", + Short: "Interact with your IAM orbs", + Long: `zitadelctl launches zitadel and simplifies common tasks such as updating your kubeconfig. +Participate in our community on https://github.com/caos/orbos +and visit our website at https://caos.ch`, + Example: `$ mkdir -p ~/.orb +$ cat > ~/.orb/myorb << EOF +> url: git@github.com:me/my-orb.git +> masterkey: "$(gopass my-secrets/orbs/myorb/masterkey)" +> repokey: | +> $(cat ~/.ssh/myorbrepo | sed s/^/\ \ /g) +> EOF +$ orbctl -f ~/.orb/myorb [command] +`, + } + + flags := cmd.PersistentFlags() + flags.StringVarP(&orbConfigPath, "orbconfig", "f", "~/.orb/config", "Path to the file containing the orbs git repo URL, deploy key and the master key for encrypting and decrypting secrets") + flags.BoolVar(&verbose, "verbose", false, "Print debug levelled logs") + + return cmd, func() (context.Context, mntr.Monitor, *orb.Orb, *git.Client, string, errFunc, error) { + + monitor := mntr.Monitor{ + OnInfo: mntr.LogMessage, + OnChange: mntr.LogMessage, + OnError: mntr.LogError, + } + + if verbose { + monitor = monitor.Verbose() + } + + prunedPath := helpers.PruneHome(orbConfigPath) + orbConfig, err := orb.ParseOrbConfig(prunedPath) + if err != nil { + orbConfig = &orb.Orb{Path: prunedPath} + return nil, mntr.Monitor{}, nil, nil, "", nil, err + } + + ctx := context.Background() + + return ctx, monitor, orbConfig, git.New(ctx, monitor, "orbos", "orbos@caos.ch"), version, func(err error) error { + if err != nil { + monitor.Error(err) + } + return nil + }, nil + } +} diff --git a/cmd/zitadelctl/cmds/start.go b/cmd/zitadelctl/cmds/start.go new file mode 100644 index 0000000000..3bbd9bd91c --- /dev/null +++ b/cmd/zitadelctl/cmds/start.go @@ -0,0 +1,82 @@ +package cmds + +import ( + "github.com/caos/orbos/pkg/kubernetes" + "github.com/caos/zitadel/operator/helpers" + "github.com/caos/zitadel/operator/start" + "github.com/spf13/cobra" +) + +func StartOperator(rv RootValues) *cobra.Command { + var ( + kubeconfig string + cmd = &cobra.Command{ + Use: "operator", + Short: "Launch a ZITADEL operator", + Long: "Ensures a desired state of ZITADEL", + } + ) + flags := cmd.Flags() + flags.StringVar(&kubeconfig, "kubeconfig", "", "Kubeconfig for ZITADEL operator deployment") + + cmd.RunE = func(cmd *cobra.Command, args []string) error { + _, monitor, orbConfig, _, version, errFunc, err := rv() + if err != nil { + return err + } + defer func() { + err = errFunc(err) + }() + + kubeconfig = helpers.PruneHome(kubeconfig) + + k8sClient, err := kubernetes.NewK8sClientWithPath(monitor, kubeconfig) + if err != nil { + monitor.Error(err) + return nil + } + + if k8sClient.Available() { + if err := start.Operator(monitor, orbConfig.Path, k8sClient, &version); err != nil { + monitor.Error(err) + return nil + } + } + return nil + } + return cmd +} + +func StartDatabase(rv RootValues) *cobra.Command { + var ( + kubeconfig string + cmd = &cobra.Command{ + Use: "database", + Short: "Launch a database operator", + Long: "Ensures a desired state of the database", + } + ) + flags := cmd.Flags() + flags.StringVar(&kubeconfig, "kubeconfig", "", "kubeconfig used by zitadel operator") + + cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { + _, monitor, orbConfig, _, version, errFunc, err := rv() + if err != nil { + return err + } + defer func() { + err = errFunc(err) + }() + + k8sClient, err := kubernetes.NewK8sClientWithPath(monitor, kubeconfig) + if err != nil { + return err + } + + if k8sClient.Available() { + return start.Database(monitor, orbConfig.Path, k8sClient, &version) + } + return nil + } + return cmd +} diff --git a/cmd/zitadelctl/cmds/takeoff.go b/cmd/zitadelctl/cmds/takeoff.go new file mode 100644 index 0000000000..9352f43fe2 --- /dev/null +++ b/cmd/zitadelctl/cmds/takeoff.go @@ -0,0 +1,127 @@ +package cmds + +import ( + orbdb "github.com/caos/zitadel/operator/database/kinds/orb" + "io/ioutil" + + "github.com/caos/zitadel/operator/helpers" + + "github.com/caos/orbos/mntr" + "github.com/caos/orbos/pkg/git" + "github.com/caos/orbos/pkg/kubernetes" + "github.com/caos/zitadel/operator/api" + "github.com/caos/zitadel/operator/zitadel/kinds/orb" + "github.com/spf13/cobra" +) + +func TakeoffCommand(rv RootValues) *cobra.Command { + var ( + kubeconfig string + cmd = &cobra.Command{ + Use: "takeoff", + Short: "Launch a ZITADEL operator on the orb", + Long: "Ensures a desired state of the resources on the orb", + } + ) + + flags := cmd.Flags() + flags.StringVar(&kubeconfig, "kubeconfig", "~/.kube/config", "Kubeconfig for ZITADEL operator deployment") + + cmd.RunE = func(cmd *cobra.Command, args []string) error { + _, monitor, orbConfig, gitClient, _, errFunc, err := rv() + if err != nil { + return err + } + defer func() { + err = errFunc(err) + }() + kubeconfig = helpers.PruneHome(kubeconfig) + + if err := gitClient.Configure(orbConfig.URL, []byte(orbConfig.Repokey)); err != nil { + monitor.Error(err) + return nil + } + + if err := gitClient.Clone(); err != nil { + monitor.Error(err) + return nil + } + + value, err := ioutil.ReadFile(kubeconfig) + if err != nil { + monitor.Error(err) + return nil + } + kubeconfigStr := string(value) + + if err := deployOperator( + monitor, + gitClient, + &kubeconfigStr, + ); err != nil { + monitor.Error(err) + } + + if err := deployDatabase( + monitor, + gitClient, + &kubeconfigStr, + ); err != nil { + monitor.Error(err) + } + return nil + } + return cmd +} + +func deployOperator(monitor mntr.Monitor, gitClient *git.Client, kubeconfig *string) error { + found, err := api.ExistsZitadelYml(gitClient) + if err != nil { + return err + } + if !found { + monitor.Info("No ZITADEL operator deployed as no zitadel.yml present") + return nil + } + + if found { + k8sClient := kubernetes.NewK8sClient(monitor, kubeconfig) + + if k8sClient.Available() { + desiredTree, err := api.ReadZitadelYml(gitClient) + if err != nil { + return err + } + if err := orb.Reconcile(monitor, desiredTree, true)(k8sClient); err != nil { + return err + } + } + } + return nil +} + +func deployDatabase(monitor mntr.Monitor, gitClient *git.Client, kubeconfig *string) error { + found, err := api.ExistsDatabaseYml(gitClient) + if err != nil { + return err + } + if found { + k8sClient := kubernetes.NewK8sClient(monitor, kubeconfig) + + if k8sClient.Available() { + tree, err := api.ReadDatabaseYml(gitClient) + if err != nil { + return err + } + + if err := orbdb.Reconcile( + monitor, + tree)(k8sClient); err != nil { + return err + } + } else { + monitor.Info("Failed to connect to k8s") + } + } + return nil +} diff --git a/cmd/zitadelctl/cmds/writesecret.go b/cmd/zitadelctl/cmds/writesecret.go new file mode 100644 index 0000000000..d49568d23d --- /dev/null +++ b/cmd/zitadelctl/cmds/writesecret.go @@ -0,0 +1,115 @@ +package cmds + +import ( + "errors" + "io/ioutil" + "os" + + "github.com/caos/orbos/pkg/secret" + "github.com/caos/zitadel/operator/secrets" + "github.com/spf13/cobra" +) + +func WriteSecretCommand(rv RootValues) *cobra.Command { + + var ( + value string + file string + stdin bool + cmd = &cobra.Command{ + Use: "writesecret [path]", + Short: "Encrypt a secret and push it to the repository", + Long: "Encrypt a secret and push it to the repository.\nIf no path is provided, a secret can interactively be chosen from a list of all possible secrets", + Args: cobra.MaximumNArgs(1), + Example: `orbctl writesecret mystaticprovider.bootstrapkey --file ~/.ssh/my-orb-bootstrap +orbctl writesecret mygceprovider.google_application_credentials_value --value "$(cat $GOOGLE_APPLICATION_CREDENTIALS)" `, + } + ) + + flags := cmd.Flags() + flags.StringVar(&value, "value", "", "Secret value to encrypt") + flags.StringVarP(&file, "file", "s", "", "File containing the value to encrypt") + flags.BoolVar(&stdin, "stdin", false, "Value to encrypt is read from standard input") + + cmd.RunE = func(cmd *cobra.Command, args []string) error { + + _, monitor, orbConfig, gitClient, _, errFunc, err := rv() + if err != nil { + return err + } + defer func() { + err = errFunc(err) + }() + + s, err := key(value, file, stdin) + if err != nil { + monitor.Error(err) + return nil + } + + if err := gitClient.Configure(orbConfig.URL, []byte(orbConfig.Repokey)); err != nil { + monitor.Error(err) + return nil + } + + if err := gitClient.Clone(); err != nil { + monitor.Error(err) + return nil + } + + path := "" + if len(args) > 0 { + path = args[0] + } + + if err := secret.Write( + monitor, + gitClient, + path, + s, + secrets.GetAllSecretsFunc(orbConfig), + secrets.PushFunc(), + ); err != nil { + monitor.Error(err) + } + return nil + } + return cmd +} + +func key(value string, file string, stdin bool) (string, error) { + + channels := 0 + if value != "" { + channels++ + } + if file != "" { + channels++ + } + if stdin { + channels++ + } + + if channels != 1 { + return "", errors.New("Key must be provided eighter by value or by file path or by standard input") + } + + if value != "" { + return value, nil + } + + readFunc := func() ([]byte, error) { + return ioutil.ReadFile(file) + } + if stdin { + readFunc = func() ([]byte, error) { + return ioutil.ReadAll(os.Stdin) + } + } + + key, err := readFunc() + if err != nil { + panic(err) + } + return string(key), err +} diff --git a/cmd/zitadelctl/main.go b/cmd/zitadelctl/main.go new file mode 100644 index 0000000000..01cf68e2de --- /dev/null +++ b/cmd/zitadelctl/main.go @@ -0,0 +1,31 @@ +package main + +import ( + "fmt" + "github.com/caos/zitadel/cmd/zitadelctl/cmds" + "os" +) + +var ( + Version = "unknown" +) + +func main() { + rootCmd, rootValues := cmds.RootCommand(Version) + rootCmd.Version = fmt.Sprintf("%s\n", Version) + + rootCmd.AddCommand( + cmds.StartOperator(rootValues), + cmds.TakeoffCommand(rootValues), + cmds.BackupListCommand(rootValues), + cmds.RestoreCommand(rootValues), + cmds.ReadSecretCommand(rootValues), + cmds.WriteSecretCommand(rootValues), + cmds.BackupCommand(rootValues), + cmds.StartDatabase(rootValues), + ) + + if err := rootCmd.Execute(); err != nil { + os.Exit(1) + } +} diff --git a/console/package-lock.json b/console/package-lock.json index dcef7a1c80..a60b752e27 100644 --- a/console/package-lock.json +++ b/console/package-lock.json @@ -4,135 +4,123 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@angular-devkit/build-angular": { - "version": "0.1100.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.1100.4.tgz", - "integrity": "sha512-qVkMbtOwlo+k8fvOBOwwfKWMx06k4I1qrdjpRYAoZCt3cdje4EBepSciLrHnTB+ouIqWxpEDfEXTYBS98tXbBg==", + "@angular-devkit/architect": { + "version": "0.1101.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1101.2.tgz", + "integrity": "sha512-MLmBfHiiyPhbFSSAX4oMecPjEuBauOui5uBpI6BKNnk/7783fznbkbAKjXlOco7M81gkNeEoHMR8c+mOfcvv7g==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1100.4", - "@angular-devkit/build-optimizer": "0.1100.4", - "@angular-devkit/build-webpack": "0.1100.4", - "@angular-devkit/core": "11.0.4", - "@babel/core": "7.12.3", - "@babel/generator": "7.12.1", - "@babel/plugin-transform-runtime": "7.12.1", - "@babel/preset-env": "7.12.1", - "@babel/runtime": "7.12.1", - "@babel/template": "7.10.4", + "@angular-devkit/core": "11.1.2", + "rxjs": "6.6.3" + } + }, + "@angular-devkit/build-angular": { + "version": "0.1101.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.1101.2.tgz", + "integrity": "sha512-EVJ7kAgy+sMnliCmHwN1niVeM7YaAvTMkF+ahImNfQRSQOW+QJ4F8vjiLtuARC6R02Yc5QPzELTHVPxC4Qll/A==", + "dev": true, + "requires": { + "@angular-devkit/architect": "0.1101.2", + "@angular-devkit/build-optimizer": "0.1101.2", + "@angular-devkit/build-webpack": "0.1101.2", + "@angular-devkit/core": "11.1.2", + "@babel/core": "7.12.10", + "@babel/generator": "7.12.11", + "@babel/plugin-transform-runtime": "7.12.10", + "@babel/preset-env": "7.12.11", + "@babel/runtime": "7.12.5", + "@babel/template": "7.12.7", "@jsdevtools/coverage-istanbul-loader": "3.0.5", - "@ngtools/webpack": "11.0.4", + "@ngtools/webpack": "11.1.2", "ansi-colors": "4.1.1", - "autoprefixer": "9.8.6", - "babel-loader": "8.1.0", + "autoprefixer": "10.2.1", + "babel-loader": "8.2.2", "browserslist": "^4.9.1", "cacache": "15.0.5", "caniuse-lite": "^1.0.30001032", - "circular-dependency-plugin": "5.2.0", - "copy-webpack-plugin": "6.2.1", - "core-js": "3.6.5", - "css-loader": "4.3.0", + "circular-dependency-plugin": "5.2.2", + "copy-webpack-plugin": "6.3.2", + "core-js": "3.8.2", + "critters": "0.0.6", + "css-loader": "5.0.1", "cssnano": "4.1.10", - "file-loader": "6.1.1", + "file-loader": "6.2.0", "find-cache-dir": "3.3.1", "glob": "7.1.6", + "https-proxy-agent": "5.0.0", "inquirer": "7.3.3", - "jest-worker": "26.5.0", + "jest-worker": "26.6.2", "karma-source-map-support": "1.4.0", - "less": "3.12.2", - "less-loader": "7.0.2", - "license-webpack-plugin": "2.3.1", + "less": "4.1.0", + "less-loader": "7.3.0", + "license-webpack-plugin": "2.3.11", "loader-utils": "2.0.0", - "mini-css-extract-plugin": "1.2.1", + "mini-css-extract-plugin": "1.3.3", "minimatch": "3.0.4", - "open": "7.3.0", - "ora": "5.1.0", + "open": "7.3.1", + "ora": "5.2.0", "parse5-html-rewriting-stream": "6.0.1", "pnp-webpack-plugin": "1.6.4", - "postcss": "7.0.32", - "postcss-import": "12.0.1", - "postcss-loader": "4.0.4", + "postcss": "8.2.4", + "postcss-import": "14.0.0", + "postcss-loader": "4.2.0", "raw-loader": "4.0.2", "regenerator-runtime": "0.13.7", "resolve-url-loader": "3.1.2", "rimraf": "3.0.2", - "rollup": "2.32.1", + "rollup": "2.36.1", "rxjs": "6.6.3", - "sass": "1.27.0", - "sass-loader": "10.0.5", - "semver": "7.3.2", + "sass": "1.32.4", + "sass-loader": "10.1.1", + "semver": "7.3.4", "source-map": "0.7.3", - "source-map-loader": "1.1.2", + "source-map-loader": "1.1.3", "source-map-support": "0.5.19", "speed-measure-webpack-plugin": "1.3.3", "style-loader": "2.0.0", "stylus": "0.54.8", - "stylus-loader": "4.3.1", - "terser": "5.3.7", + "stylus-loader": "4.3.2", + "terser": "5.5.1", "terser-webpack-plugin": "4.2.3", "text-table": "0.2.0", "tree-kill": "1.2.2", "webpack": "4.44.2", "webpack-dev-middleware": "3.7.2", - "webpack-dev-server": "3.11.0", - "webpack-merge": "5.2.0", - "webpack-sources": "2.0.1", - "webpack-subresource-integrity": "1.5.1", + "webpack-dev-server": "3.11.1", + "webpack-merge": "5.7.3", + "webpack-sources": "2.2.0", + "webpack-subresource-integrity": "1.5.2", "worker-plugin": "5.0.0" }, "dependencies": { - "@angular-devkit/architect": { - "version": "0.1100.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1100.4.tgz", - "integrity": "sha512-hzTfcSUwM0jsSt9HvvSFyaoAhX9k73L7y4kmkghzIFhKhIKOp/7o3n7hAFwN/jWKKmVQpPKnYmqzm9H9OveaCQ==", - "dev": true, - "requires": { - "@angular-devkit/core": "11.0.4", - "rxjs": "6.6.3" - } - }, - "@angular-devkit/core": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.0.4.tgz", - "integrity": "sha512-LgTvhZ3Ycz0QvNAH/zO1rpQQDn2JN8u9/Awy1gW/XeCC3FYmxeOj/2JCFzlKah3wJv16nMqro5WTppHt8Y++PA==", - "dev": true, - "requires": { - "ajv": "6.12.6", - "fast-json-stable-stringify": "2.1.0", - "magic-string": "0.25.7", - "rxjs": "6.6.3", - "source-map": "0.7.3" - } - }, "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" } }, "@babel/core": { - "version": "7.12.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.3.tgz", - "integrity": "sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", + "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.1", + "@babel/generator": "^7.12.10", "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.1", - "@babel/parser": "^7.12.3", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1", + "@babel/helpers": "^7.12.5", + "@babel/parser": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.10", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", "json5": "^2.1.2", "lodash": "^4.17.19", - "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" }, @@ -152,12 +140,12 @@ } }, "@babel/generator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.1.tgz", - "integrity": "sha512-DB+6rafIdc9o72Yc3/Ph5h+6hUjeOp66pF0naQBgUFFuPqzQwIlPTm3xZR7YNvduIMtkDIj2t21LSQwnbCrXvg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", + "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", "dev": true, "requires": { - "@babel/types": "^7.12.1", + "@babel/types": "^7.12.11", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -170,6 +158,26 @@ } } }, + "@babel/helper-function-name": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, "@babel/helper-member-expression-to-functions": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", @@ -205,16 +213,25 @@ "lodash": "^4.17.19" } }, - "@babel/helper-replace-supers": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz", - "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==", + "@babel/helper-optimise-call-expression": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.1", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.12.5", - "@babel/types": "^7.12.5" + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-replace-supers": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", + "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.12.7", + "@babel/helper-optimise-call-expression": "^7.12.10", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.11" } }, "@babel/helper-simple-access": { @@ -227,12 +244,12 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", + "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.12.11" } }, "@babel/helpers": { @@ -258,79 +275,100 @@ } }, "@babel/parser": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.10.tgz", - "integrity": "sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", "dev": true }, "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" } }, "@babel/traverse": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.10.tgz", - "integrity": "sha512-6aEtf0IeRgbYWzta29lePeYSk+YAFIC3kyqESeft8o5CkFlYIMX+EQDDWEiAQ9LHOA3d0oHdgrSsID/CKqXJlg==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", + "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.10", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.10", - "@babel/types": "^7.12.10", + "@babel/code-frame": "^7.12.11", + "@babel/generator": "^7.12.11", + "@babel/helper-function-name": "^7.12.11", + "@babel/helper-split-export-declaration": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/types": "^7.12.12", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" }, "dependencies": { - "@babel/generator": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.10.tgz", - "integrity": "sha512-6mCdfhWgmqLdtTkhXjnIz0LcdVCd26wS2JXRtj2XY0u5klDsXBREA/pG5NVOuVnF2LUrBGNFtQkIqqTbblg0ww==", - "dev": true, - "requires": { - "@babel/types": "^7.12.10", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", "dev": true } } }, - "@babel/types": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz", - "integrity": "sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw==", + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" + "debug": "4" } }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "autoprefixer": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.2.1.tgz", + "integrity": "sha512-dwP0UjyYvROUvtU+boBx8ff5pPWami1NGTrJs9YUsS/oZVbRAcdNHOOuXSA1fc46tgKqe072cVaKD69rvCc3QQ==", "dev": true, "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "browserslist": "^4.16.1", + "caniuse-lite": "^1.0.30001173", + "colorette": "^1.2.1", + "fraction.js": "^4.0.13", + "normalize-range": "^0.1.2", + "postcss-value-parser": "^4.1.0" + }, + "dependencies": { + "browserslist": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", + "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001181", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.649", + "escalade": "^3.1.1", + "node-releases": "^1.1.70" + } + }, + "caniuse-lite": { + "version": "1.0.30001181", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001181.tgz", + "integrity": "sha512-m5ul/ARCX50JB8BSNM+oiPmQrR5UmngaQ3QThTTp5HcIIQGP/nPBs82BYLE+tigzm3VW+F4BJIhUyaVtEweelQ==", + "dev": true + } } }, "debug": { @@ -342,6 +380,53 @@ "ms": "2.1.2" } }, + "electron-to-chromium": { + "version": "1.3.649", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.649.tgz", + "integrity": "sha512-ojGDupQ3UMkvPWcTICe4JYe17+o9OLiFMPoduoR72Zp2ILt1mRVeqnxBEd6s/ptekrnsFU+0A4lStfBe/wyG/A==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "node-releases": { + "version": "1.1.70", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.70.tgz", + "integrity": "sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==", + "dev": true + }, + "postcss": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.4.tgz", + "integrity": "sha512-kRFftRoExRVXZlwUuay9iC824qmXPcQQVzAjbCCgjpXnkdMCJYBu2gTwAaFBzv8ewND6O8xFb3aELmEkh9zTzg==", + "dev": true, + "requires": { + "colorette": "^1.2.1", + "nanoid": "^3.1.20", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -352,10 +437,13 @@ } }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "source-map": { "version": "0.7.3", @@ -366,16 +454,16 @@ } }, "@angular-devkit/build-optimizer": { - "version": "0.1100.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.1100.4.tgz", - "integrity": "sha512-C05y4qMb05PWR7l1gZwRQKiB6KIDq+p72r8Yr6jm0UO6raOtMM72R8nHnioMnGJcFtZDEAYXEF+X7soI3MMlfw==", + "version": "0.1101.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.1101.2.tgz", + "integrity": "sha512-ARcUcEwaAR3n0gUq2hCx4eXONdnKKXTYSaw2GUHtraBDp+m/vFcE6Ufxyki453eHbHtaQ9yjXOcBqu86u1u8hA==", "dev": true, "requires": { "loader-utils": "2.0.0", "source-map": "0.7.3", - "tslib": "2.0.3", - "typescript": "4.0.5", - "webpack-sources": "2.0.1" + "tslib": "2.1.0", + "typescript": "4.1.3", + "webpack-sources": "2.2.0" }, "dependencies": { "source-map": { @@ -383,43 +471,45 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", "dev": true + }, + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + }, + "typescript": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", + "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", + "dev": true } } }, "@angular-devkit/build-webpack": { - "version": "0.1100.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1100.4.tgz", - "integrity": "sha512-uxe8gNSej3KF1FgqNtJmuRDbbINh3yLtXanXhRxFQLUj8IiNR8IciIVvy6RfXC5gqxcWwy1cOefJLLnuN9AOxQ==", + "version": "0.1101.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1101.2.tgz", + "integrity": "sha512-T8+LjKdxk1faQA4Dh3PYkRbIBLE6Tjv5SNZmdDXpvGoyxS9FmLgLDXQZqXkYgiAHwH6PxhoQX4iVxkHHFkkHog==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1100.4", - "@angular-devkit/core": "11.0.4", + "@angular-devkit/architect": "0.1101.2", + "@angular-devkit/core": "11.1.2", "rxjs": "6.6.3" + } + }, + "@angular-devkit/core": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.1.2.tgz", + "integrity": "sha512-V7zOMqL2l56JcwXVyswkG+7+t67r9XtkrVzRcG2Z5ZYwafU+iKWMwg5kBFZr1SX7fM1M9E4MpskxqtagQeUKng==", + "dev": true, + "requires": { + "ajv": "6.12.6", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.3", + "source-map": "0.7.3" }, "dependencies": { - "@angular-devkit/architect": { - "version": "0.1100.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1100.4.tgz", - "integrity": "sha512-hzTfcSUwM0jsSt9HvvSFyaoAhX9k73L7y4kmkghzIFhKhIKOp/7o3n7hAFwN/jWKKmVQpPKnYmqzm9H9OveaCQ==", - "dev": true, - "requires": { - "@angular-devkit/core": "11.0.4", - "rxjs": "6.6.3" - } - }, - "@angular-devkit/core": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.0.4.tgz", - "integrity": "sha512-LgTvhZ3Ycz0QvNAH/zO1rpQQDn2JN8u9/Awy1gW/XeCC3FYmxeOj/2JCFzlKah3wJv16nMqro5WTppHt8Y++PA==", - "dev": true, - "requires": { - "ajv": "6.12.6", - "fast-json-stable-stringify": "2.1.0", - "magic-string": "0.25.7", - "rxjs": "6.6.3", - "source-map": "0.7.3" - } - }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -440,6 +530,17 @@ } } }, + "@angular-devkit/schematics": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-11.1.2.tgz", + "integrity": "sha512-wIWI4+EPsjbN+23Rs0zE4GarKrUm8gMR3MpGAtlEmGG2ZsXEVdfiKUebBdWGrx0sEfgLN9JfePbZQFvqN5ifyw==", + "dev": true, + "requires": { + "@angular-devkit/core": "11.1.2", + "ora": "5.2.0", + "rxjs": "6.6.3" + } + }, "@angular/animations": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-11.0.0.tgz", @@ -458,95 +559,56 @@ } }, "@angular/cli": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-11.0.4.tgz", - "integrity": "sha512-VkE/gx6P80EJHg13fG+gkZfd2DJmRaDAtnamcCGM4AThzoUN9XBdxc24uMLEzBb0/mJ4vpMK9+WTNIdMmzl+Tg==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-11.1.2.tgz", + "integrity": "sha512-qOAkxCzBPm+QdXpSHxLERw1Vag8S0JHMY0zCwtG63XFvwHZCIihHRkOR3xHDWlVnGTmnUixg4Mt5s/4GGPuDJg==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1100.4", - "@angular-devkit/core": "11.0.4", - "@angular-devkit/schematics": "11.0.4", - "@schematics/angular": "11.0.4", - "@schematics/update": "0.1100.4", + "@angular-devkit/architect": "0.1101.2", + "@angular-devkit/core": "11.1.2", + "@angular-devkit/schematics": "11.1.2", + "@schematics/angular": "11.1.2", + "@schematics/update": "0.1101.2", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.1", - "debug": "4.2.0", - "ini": "1.3.5", + "debug": "4.3.1", + "ini": "2.0.0", "inquirer": "7.3.3", + "jsonc-parser": "3.0.0", "npm-package-arg": "8.1.0", "npm-pick-manifest": "6.1.0", - "open": "7.3.0", - "pacote": "9.5.12", - "resolve": "1.18.1", + "open": "7.3.1", + "pacote": "11.1.14", + "resolve": "1.19.0", "rimraf": "3.0.2", - "semver": "7.3.2", - "symbol-observable": "2.0.3", + "semver": "7.3.4", + "symbol-observable": "3.0.0", "universal-analytics": "0.4.23", - "uuid": "8.3.1" + "uuid": "8.3.2" }, "dependencies": { - "@angular-devkit/architect": { - "version": "0.1100.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1100.4.tgz", - "integrity": "sha512-hzTfcSUwM0jsSt9HvvSFyaoAhX9k73L7y4kmkghzIFhKhIKOp/7o3n7hAFwN/jWKKmVQpPKnYmqzm9H9OveaCQ==", - "dev": true, - "requires": { - "@angular-devkit/core": "11.0.4", - "rxjs": "6.6.3" - } - }, - "@angular-devkit/core": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.0.4.tgz", - "integrity": "sha512-LgTvhZ3Ycz0QvNAH/zO1rpQQDn2JN8u9/Awy1gW/XeCC3FYmxeOj/2JCFzlKah3wJv16nMqro5WTppHt8Y++PA==", - "dev": true, - "requires": { - "ajv": "6.12.6", - "fast-json-stable-stringify": "2.1.0", - "magic-string": "0.25.7", - "rxjs": "6.6.3", - "source-map": "0.7.3" - } - }, - "@angular-devkit/schematics": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-11.0.4.tgz", - "integrity": "sha512-fFC7qW9A1bFAZgpCfkezBA4WCRzfVFgOzwPpyt65rgSrzw0+EeHjcrUIcXlhyOXAFrTHtA9oLCfEeSjSx5HBEA==", - "dev": true, - "requires": { - "@angular-devkit/core": "11.0.4", - "ora": "5.1.0", - "rxjs": "6.6.3" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" } }, + "ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true + }, "resolve": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", - "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", "dev": true, "requires": { - "is-core-module": "^2.0.0", + "is-core-module": "^2.1.0", "path-parse": "^1.0.6" } }, @@ -560,22 +622,13 @@ } }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - }, - "uuid": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", - "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==", - "dev": true + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, @@ -778,9 +831,9 @@ } }, "@angular/language-service": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-11.0.4.tgz", - "integrity": "sha512-KtQxVSlZi3SwZEN4E56KHkNTFEYa3FPZfLJFm6WD1dSobFyMwJgvztO08GWSaT4S0ht0NNRD2IRt0XzBYuZkag==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-11.1.1.tgz", + "integrity": "sha512-87PYlTBBaMr0DYMYxkyeFas1qXIRYM0soNYkXC8yE+hxkGWTN15Zjk19+lx5z43++uNOiZw1mqnKTJoO46kE6A==", "dev": true }, "@angular/material": { @@ -916,13 +969,19 @@ "@babel/types": "^7.12.10" }, "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/types": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz", - "integrity": "sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } @@ -952,28 +1011,28 @@ }, "dependencies": { "browserslist": { - "version": "4.16.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.0.tgz", - "integrity": "sha512-/j6k8R0p3nxOC6kx5JGAxsnhc9ixaWJfYc+TNTzxg6+ARaESAvQGV7h0uNOB4t+pLQJZWzcrMxXOxjgsCj3dqQ==", + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", + "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001165", + "caniuse-lite": "^1.0.30001181", "colorette": "^1.2.1", - "electron-to-chromium": "^1.3.621", + "electron-to-chromium": "^1.3.649", "escalade": "^3.1.1", - "node-releases": "^1.1.67" + "node-releases": "^1.1.70" } }, "caniuse-lite": { - "version": "1.0.30001165", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001165.tgz", - "integrity": "sha512-8cEsSMwXfx7lWSUMA2s08z9dIgsnR5NAqjXP23stdsU3AUWkCr/rr4s4OFtHXn5XXr6+7kam3QFVoYyXNPdJPA==", + "version": "1.0.30001181", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001181.tgz", + "integrity": "sha512-m5ul/ARCX50JB8BSNM+oiPmQrR5UmngaQ3QThTTp5HcIIQGP/nPBs82BYLE+tigzm3VW+F4BJIhUyaVtEweelQ==", "dev": true }, "electron-to-chromium": { - "version": "1.3.625", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.625.tgz", - "integrity": "sha512-CsLk/r0C9dAzVPa9QF74HIXduxaucsaRfqiOYvIv2PRhvyC6EOqc/KbpgToQuDVgPf3sNAFZi3iBu4vpGOwGag==", + "version": "1.3.649", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.649.tgz", + "integrity": "sha512-ojGDupQ3UMkvPWcTICe4JYe17+o9OLiFMPoduoR72Zp2ILt1mRVeqnxBEd6s/ptekrnsFU+0A4lStfBe/wyG/A==", "dev": true }, "escalade": { @@ -983,9 +1042,9 @@ "dev": true }, "node-releases": { - "version": "1.1.67", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.67.tgz", - "integrity": "sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg==", + "version": "1.1.70", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.70.tgz", + "integrity": "sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==", "dev": true } } @@ -1004,25 +1063,34 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" } }, "@babel/generator": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.10.tgz", - "integrity": "sha512-6mCdfhWgmqLdtTkhXjnIz0LcdVCd26wS2JXRtj2XY0u5klDsXBREA/pG5NVOuVnF2LUrBGNFtQkIqqTbblg0ww==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", + "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", "dev": true, "requires": { - "@babel/types": "^7.12.10", + "@babel/types": "^7.12.11", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, + "@babel/helper-get-function-arity": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, "@babel/helper-member-expression-to-functions": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", @@ -1033,17 +1101,34 @@ } }, "@babel/helper-replace-supers": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz", - "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", + "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.1", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.12.5", - "@babel/types": "^7.12.5" + "@babel/helper-member-expression-to-functions": "^7.12.7", + "@babel/helper-optimise-call-expression": "^7.12.10", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.11" + }, + "dependencies": { + "@babel/helper-optimise-call-expression": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + } } }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/highlight": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", @@ -1056,46 +1141,68 @@ } }, "@babel/parser": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.10.tgz", - "integrity": "sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", "dev": true }, - "@babel/traverse": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.10.tgz", - "integrity": "sha512-6aEtf0IeRgbYWzta29lePeYSk+YAFIC3kyqESeft8o5CkFlYIMX+EQDDWEiAQ9LHOA3d0oHdgrSsID/CKqXJlg==", + "@babel/template": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.10", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.10", - "@babel/types": "^7.12.10", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" + } + }, + "@babel/traverse": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", + "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.11", + "@babel/generator": "^7.12.11", + "@babel/helper-function-name": "^7.12.11", + "@babel/helper-split-export-declaration": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/types": "^7.12.12", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" }, "dependencies": { - "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "@babel/helper-function-name": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", + "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "dev": true, + "requires": { + "@babel/types": "^7.12.11" } } } }, "@babel/types": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz", - "integrity": "sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } @@ -1147,13 +1254,19 @@ "@babel/types": "^7.12.1" }, "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/types": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz", - "integrity": "sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } @@ -1314,13 +1427,19 @@ "@babel/types": "^7.12.1" }, "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/types": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz", - "integrity": "sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } @@ -1391,13 +1510,19 @@ "@babel/types": "^7.12.1" }, "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/types": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz", - "integrity": "sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } @@ -1420,9 +1545,9 @@ "dev": true }, "@babel/helper-validator-option": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.1.tgz", - "integrity": "sha512-YpJabsXlJVWP0USHjnC/AQDTLlZERbON577YUVO/wLpqyj6HAtVYnWaQaN0iUN+1/tWn3c+uKKXjRut5115Y2A==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz", + "integrity": "sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw==", "dev": true }, "@babel/helper-wrap-function": { @@ -1438,9 +1563,9 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" @@ -1458,9 +1583,9 @@ } }, "@babel/parser": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.10.tgz", - "integrity": "sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", "dev": true }, "@babel/template": { @@ -1474,13 +1599,19 @@ "@babel/types": "^7.12.7" }, "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/types": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz", - "integrity": "sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } @@ -1551,9 +1682,9 @@ "dev": true }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.1.tgz", - "integrity": "sha512-d+/o30tJxFxrA1lhzJqiUcEJdI6jKlNregCv5bASeGf2Q4MXmnwH7viDo7nhx1/ohf09oaH8j1GVYG/e3Yqk6A==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.12.tgz", + "integrity": "sha512-nrz9y0a4xmUrRq51bYkWJIO5SBZyG2ys2qinHsN0zHDHVsUaModrkpyWWWXfGqYQmOL3x9sQIcTNN/pBGpo09A==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -1820,13 +1951,19 @@ "@babel/types": "^7.12.5" } }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/types": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz", - "integrity": "sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } @@ -1843,9 +1980,9 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.1.tgz", - "integrity": "sha512-zJyAC9sZdE60r1nVQHblcfCj29Dh2Y0DOvlMkcqSo0ckqjiCwNiUezUKw+RjOCwGfpLRwnAeQ2XlLpsnGkvv9w==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz", + "integrity": "sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" @@ -1868,25 +2005,34 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" } }, "@babel/generator": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.10.tgz", - "integrity": "sha512-6mCdfhWgmqLdtTkhXjnIz0LcdVCd26wS2JXRtj2XY0u5klDsXBREA/pG5NVOuVnF2LUrBGNFtQkIqqTbblg0ww==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", + "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", "dev": true, "requires": { - "@babel/types": "^7.12.10", + "@babel/types": "^7.12.11", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, + "@babel/helper-get-function-arity": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, "@babel/helper-member-expression-to-functions": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", @@ -1897,17 +2043,34 @@ } }, "@babel/helper-replace-supers": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz", - "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", + "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.1", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.12.5", - "@babel/types": "^7.12.5" + "@babel/helper-member-expression-to-functions": "^7.12.7", + "@babel/helper-optimise-call-expression": "^7.12.10", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.11" + }, + "dependencies": { + "@babel/helper-optimise-call-expression": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + } } }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/highlight": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", @@ -1920,46 +2083,68 @@ } }, "@babel/parser": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.10.tgz", - "integrity": "sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", "dev": true }, - "@babel/traverse": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.10.tgz", - "integrity": "sha512-6aEtf0IeRgbYWzta29lePeYSk+YAFIC3kyqESeft8o5CkFlYIMX+EQDDWEiAQ9LHOA3d0oHdgrSsID/CKqXJlg==", + "@babel/template": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.10", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.10", - "@babel/types": "^7.12.10", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" + } + }, + "@babel/traverse": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", + "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.11", + "@babel/generator": "^7.12.11", + "@babel/helper-function-name": "^7.12.11", + "@babel/helper-split-export-declaration": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/types": "^7.12.12", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" }, "dependencies": { - "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "@babel/helper-function-name": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", + "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "dev": true, + "requires": { + "@babel/types": "^7.12.11" } } } }, "@babel/types": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz", - "integrity": "sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } @@ -2077,25 +2262,45 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" } }, "@babel/generator": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.10.tgz", - "integrity": "sha512-6mCdfhWgmqLdtTkhXjnIz0LcdVCd26wS2JXRtj2XY0u5klDsXBREA/pG5NVOuVnF2LUrBGNFtQkIqqTbblg0ww==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", + "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", "dev": true, "requires": { - "@babel/types": "^7.12.10", + "@babel/types": "^7.12.11", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, + "@babel/helper-function-name": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, "@babel/helper-member-expression-to-functions": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", @@ -2131,16 +2336,25 @@ "lodash": "^4.17.19" } }, - "@babel/helper-replace-supers": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz", - "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==", + "@babel/helper-optimise-call-expression": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.1", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.12.5", - "@babel/types": "^7.12.5" + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-replace-supers": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", + "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.12.7", + "@babel/helper-optimise-call-expression": "^7.12.10", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.11" } }, "@babel/helper-simple-access": { @@ -2153,12 +2367,12 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", + "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.12.11" } }, "@babel/highlight": { @@ -2173,9 +2387,9 @@ } }, "@babel/parser": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.10.tgz", - "integrity": "sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", "dev": true }, "@babel/template": { @@ -2190,31 +2404,39 @@ } }, "@babel/traverse": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.10.tgz", - "integrity": "sha512-6aEtf0IeRgbYWzta29lePeYSk+YAFIC3kyqESeft8o5CkFlYIMX+EQDDWEiAQ9LHOA3d0oHdgrSsID/CKqXJlg==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", + "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.10", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.10", - "@babel/types": "^7.12.10", + "@babel/code-frame": "^7.12.11", + "@babel/generator": "^7.12.11", + "@babel/helper-function-name": "^7.12.11", + "@babel/helper-split-export-declaration": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/types": "^7.12.12", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz", - "integrity": "sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + } } }, "debug": { @@ -2247,25 +2469,45 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" } }, "@babel/generator": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.10.tgz", - "integrity": "sha512-6mCdfhWgmqLdtTkhXjnIz0LcdVCd26wS2JXRtj2XY0u5klDsXBREA/pG5NVOuVnF2LUrBGNFtQkIqqTbblg0ww==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", + "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", "dev": true, "requires": { - "@babel/types": "^7.12.10", + "@babel/types": "^7.12.11", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, + "@babel/helper-function-name": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, "@babel/helper-member-expression-to-functions": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", @@ -2301,16 +2543,25 @@ "lodash": "^4.17.19" } }, - "@babel/helper-replace-supers": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz", - "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==", + "@babel/helper-optimise-call-expression": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.1", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.12.5", - "@babel/types": "^7.12.5" + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-replace-supers": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", + "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.12.7", + "@babel/helper-optimise-call-expression": "^7.12.10", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.11" } }, "@babel/helper-simple-access": { @@ -2323,12 +2574,12 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", + "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.12.11" } }, "@babel/highlight": { @@ -2343,9 +2594,9 @@ } }, "@babel/parser": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.10.tgz", - "integrity": "sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", "dev": true }, "@babel/template": { @@ -2360,31 +2611,39 @@ } }, "@babel/traverse": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.10.tgz", - "integrity": "sha512-6aEtf0IeRgbYWzta29lePeYSk+YAFIC3kyqESeft8o5CkFlYIMX+EQDDWEiAQ9LHOA3d0oHdgrSsID/CKqXJlg==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", + "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.10", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.10", - "@babel/types": "^7.12.10", + "@babel/code-frame": "^7.12.11", + "@babel/generator": "^7.12.11", + "@babel/helper-function-name": "^7.12.11", + "@babel/helper-split-export-declaration": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/types": "^7.12.12", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz", - "integrity": "sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + } } }, "debug": { @@ -2418,25 +2677,45 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" } }, "@babel/generator": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.10.tgz", - "integrity": "sha512-6mCdfhWgmqLdtTkhXjnIz0LcdVCd26wS2JXRtj2XY0u5klDsXBREA/pG5NVOuVnF2LUrBGNFtQkIqqTbblg0ww==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", + "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", "dev": true, "requires": { - "@babel/types": "^7.12.10", + "@babel/types": "^7.12.11", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, + "@babel/helper-function-name": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, "@babel/helper-member-expression-to-functions": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", @@ -2472,16 +2751,25 @@ "lodash": "^4.17.19" } }, - "@babel/helper-replace-supers": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz", - "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==", + "@babel/helper-optimise-call-expression": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.1", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.12.5", - "@babel/types": "^7.12.5" + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-replace-supers": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", + "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.12.7", + "@babel/helper-optimise-call-expression": "^7.12.10", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.11" } }, "@babel/helper-simple-access": { @@ -2494,12 +2782,12 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", + "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.12.11" } }, "@babel/highlight": { @@ -2514,9 +2802,9 @@ } }, "@babel/parser": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.10.tgz", - "integrity": "sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", "dev": true }, "@babel/template": { @@ -2531,31 +2819,39 @@ } }, "@babel/traverse": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.10.tgz", - "integrity": "sha512-6aEtf0IeRgbYWzta29lePeYSk+YAFIC3kyqESeft8o5CkFlYIMX+EQDDWEiAQ9LHOA3d0oHdgrSsID/CKqXJlg==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", + "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.10", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.10", - "@babel/types": "^7.12.10", + "@babel/code-frame": "^7.12.11", + "@babel/generator": "^7.12.11", + "@babel/helper-function-name": "^7.12.11", + "@babel/helper-split-export-declaration": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/types": "^7.12.12", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz", - "integrity": "sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + } } }, "debug": { @@ -2586,25 +2882,45 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" } }, "@babel/generator": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.10.tgz", - "integrity": "sha512-6mCdfhWgmqLdtTkhXjnIz0LcdVCd26wS2JXRtj2XY0u5klDsXBREA/pG5NVOuVnF2LUrBGNFtQkIqqTbblg0ww==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", + "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", "dev": true, "requires": { - "@babel/types": "^7.12.10", + "@babel/types": "^7.12.11", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, + "@babel/helper-function-name": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, "@babel/helper-member-expression-to-functions": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", @@ -2640,16 +2956,25 @@ "lodash": "^4.17.19" } }, - "@babel/helper-replace-supers": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz", - "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==", + "@babel/helper-optimise-call-expression": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.1", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.12.5", - "@babel/types": "^7.12.5" + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-replace-supers": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", + "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.12.7", + "@babel/helper-optimise-call-expression": "^7.12.10", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.11" } }, "@babel/helper-simple-access": { @@ -2662,12 +2987,12 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", + "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.12.11" } }, "@babel/highlight": { @@ -2682,9 +3007,9 @@ } }, "@babel/parser": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.10.tgz", - "integrity": "sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", "dev": true }, "@babel/template": { @@ -2699,31 +3024,39 @@ } }, "@babel/traverse": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.10.tgz", - "integrity": "sha512-6aEtf0IeRgbYWzta29lePeYSk+YAFIC3kyqESeft8o5CkFlYIMX+EQDDWEiAQ9LHOA3d0oHdgrSsID/CKqXJlg==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", + "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.10", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.10", - "@babel/types": "^7.12.10", + "@babel/code-frame": "^7.12.11", + "@babel/generator": "^7.12.11", + "@babel/helper-function-name": "^7.12.11", + "@babel/helper-split-export-declaration": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/types": "^7.12.12", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz", - "integrity": "sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + } } }, "debug": { @@ -2772,25 +3105,45 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" } }, "@babel/generator": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.10.tgz", - "integrity": "sha512-6mCdfhWgmqLdtTkhXjnIz0LcdVCd26wS2JXRtj2XY0u5klDsXBREA/pG5NVOuVnF2LUrBGNFtQkIqqTbblg0ww==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", + "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", "dev": true, "requires": { - "@babel/types": "^7.12.10", + "@babel/types": "^7.12.11", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, + "@babel/helper-function-name": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, "@babel/helper-member-expression-to-functions": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", @@ -2800,27 +3153,42 @@ "@babel/types": "^7.12.7" } }, - "@babel/helper-replace-supers": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz", - "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==", + "@babel/helper-optimise-call-expression": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.1", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.12.5", - "@babel/types": "^7.12.5" + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-replace-supers": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", + "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.12.7", + "@babel/helper-optimise-call-expression": "^7.12.10", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.11" } }, "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", + "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.12.11" } }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/highlight": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", @@ -2833,35 +3201,46 @@ } }, "@babel/parser": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.10.tgz", - "integrity": "sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", "dev": true }, - "@babel/traverse": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.10.tgz", - "integrity": "sha512-6aEtf0IeRgbYWzta29lePeYSk+YAFIC3kyqESeft8o5CkFlYIMX+EQDDWEiAQ9LHOA3d0oHdgrSsID/CKqXJlg==", + "@babel/template": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.10", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.12.10", - "@babel/types": "^7.12.10", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" + } + }, + "@babel/traverse": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", + "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.11", + "@babel/generator": "^7.12.11", + "@babel/helper-function-name": "^7.12.11", + "@babel/helper-split-export-declaration": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/types": "^7.12.12", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz", - "integrity": "sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } @@ -2920,14 +3299,13 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.1.tgz", - "integrity": "sha512-Ac/H6G9FEIkS2tXsZjL4RAdS3L3WHxci0usAnz7laPWUmFiGtj7tIASChqKZMHTSQTQY6xDbOq+V1/vIq3QrWg==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.10.tgz", + "integrity": "sha512-xOrUfzPxw7+WDm9igMgQCbO3cJKymX7dFdsgRr1eu9n3KjjyU4pptIXbXPseQDquw+W+RuJEJMHKHNsPNNm3CA==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.12.1", + "@babel/helper-module-imports": "^7.12.5", "@babel/helper-plugin-utils": "^7.10.4", - "resolve": "^1.8.1", "semver": "^5.5.1" }, "dependencies": { @@ -2940,13 +3318,19 @@ "@babel/types": "^7.12.5" } }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/types": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz", - "integrity": "sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } @@ -3019,16 +3403,16 @@ } }, "@babel/preset-env": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.1.tgz", - "integrity": "sha512-H8kxXmtPaAGT7TyBvSSkoSTUK6RHh61So05SyEbpmr0MCZrsNYn7mGMzzeYoOUCdHzww61k8XBft2TaES+xPLg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.11.tgz", + "integrity": "sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw==", "dev": true, "requires": { - "@babel/compat-data": "^7.12.1", - "@babel/helper-compilation-targets": "^7.12.1", - "@babel/helper-module-imports": "^7.12.1", + "@babel/compat-data": "^7.12.7", + "@babel/helper-compilation-targets": "^7.12.5", + "@babel/helper-module-imports": "^7.12.5", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-validator-option": "^7.12.1", + "@babel/helper-validator-option": "^7.12.11", "@babel/plugin-proposal-async-generator-functions": "^7.12.1", "@babel/plugin-proposal-class-properties": "^7.12.1", "@babel/plugin-proposal-dynamic-import": "^7.12.1", @@ -3036,10 +3420,10 @@ "@babel/plugin-proposal-json-strings": "^7.12.1", "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", - "@babel/plugin-proposal-numeric-separator": "^7.12.1", + "@babel/plugin-proposal-numeric-separator": "^7.12.7", "@babel/plugin-proposal-object-rest-spread": "^7.12.1", "@babel/plugin-proposal-optional-catch-binding": "^7.12.1", - "@babel/plugin-proposal-optional-chaining": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.12.7", "@babel/plugin-proposal-private-methods": "^7.12.1", "@babel/plugin-proposal-unicode-property-regex": "^7.12.1", "@babel/plugin-syntax-async-generators": "^7.8.0", @@ -3057,7 +3441,7 @@ "@babel/plugin-transform-arrow-functions": "^7.12.1", "@babel/plugin-transform-async-to-generator": "^7.12.1", "@babel/plugin-transform-block-scoped-functions": "^7.12.1", - "@babel/plugin-transform-block-scoping": "^7.12.1", + "@babel/plugin-transform-block-scoping": "^7.12.11", "@babel/plugin-transform-classes": "^7.12.1", "@babel/plugin-transform-computed-properties": "^7.12.1", "@babel/plugin-transform-destructuring": "^7.12.1", @@ -3081,14 +3465,14 @@ "@babel/plugin-transform-reserved-words": "^7.12.1", "@babel/plugin-transform-shorthand-properties": "^7.12.1", "@babel/plugin-transform-spread": "^7.12.1", - "@babel/plugin-transform-sticky-regex": "^7.12.1", + "@babel/plugin-transform-sticky-regex": "^7.12.7", "@babel/plugin-transform-template-literals": "^7.12.1", - "@babel/plugin-transform-typeof-symbol": "^7.12.1", + "@babel/plugin-transform-typeof-symbol": "^7.12.10", "@babel/plugin-transform-unicode-escapes": "^7.12.1", "@babel/plugin-transform-unicode-regex": "^7.12.1", "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.12.1", - "core-js-compat": "^3.6.2", + "@babel/types": "^7.12.11", + "core-js-compat": "^3.8.0", "semver": "^5.5.0" }, "dependencies": { @@ -3101,13 +3485,19 @@ "@babel/types": "^7.12.5" } }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/types": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.10.tgz", - "integrity": "sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } @@ -3128,9 +3518,9 @@ } }, "@babel/runtime": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.1.tgz", - "integrity": "sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -3243,47 +3633,14 @@ } }, "@ngtools/webpack": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-11.0.4.tgz", - "integrity": "sha512-MAV7inQmsMISTnDcXwyRX5oJZx8F7K/tZRLJciQwkM0DqZyq8fI9KDRwBcmYeQ+J0mSJV9LUVdExmpulpkywqw==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-11.1.2.tgz", + "integrity": "sha512-x/HVx4doKu4gAwGGk+C89JCFe5GF8Te7I7uvwMTqEXr+Ua9YHYvN/q2IwLdhIXPB4ilBSIjrb9zm05yBvBTAeg==", "dev": true, "requires": { - "@angular-devkit/core": "11.0.4", - "enhanced-resolve": "5.3.1", - "webpack-sources": "2.0.1" - }, - "dependencies": { - "@angular-devkit/core": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.0.4.tgz", - "integrity": "sha512-LgTvhZ3Ycz0QvNAH/zO1rpQQDn2JN8u9/Awy1gW/XeCC3FYmxeOj/2JCFzlKah3wJv16nMqro5WTppHt8Y++PA==", - "dev": true, - "requires": { - "ajv": "6.12.6", - "fast-json-stable-stringify": "2.1.0", - "magic-string": "0.25.7", - "rxjs": "6.6.3", - "source-map": "0.7.3" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - } + "@angular-devkit/core": "11.1.2", + "enhanced-resolve": "5.6.0", + "webpack-sources": "2.2.0" } }, "@ngx-translate/core": { @@ -3328,13 +3685,27 @@ "fastq": "^1.6.0" } }, - "@npmcli/move-file": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.0.1.tgz", - "integrity": "sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw==", + "@npmcli/ci-detect": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@npmcli/ci-detect/-/ci-detect-1.3.0.tgz", + "integrity": "sha512-oN3y7FAROHhrAt7Rr7PnTSwrHrZVRTS2ZbyxeQwSSYD0ifwM3YNgQqbaRmjcWoPyq77MjchusjJDspbzMmip1Q==", + "dev": true + }, + "@npmcli/git": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-2.0.4.tgz", + "integrity": "sha512-OJZCmJ9DNn1cz9HPXXsPmUBnqaArot3CGYo63CyajHQk+g87rPXVOJByGsskQJhPsUUEXJcsZ2Q6bWd2jSwnBA==", "dev": true, "requires": { - "mkdirp": "^1.0.4" + "@npmcli/promise-spawn": "^1.1.0", + "lru-cache": "^6.0.0", + "mkdirp": "^1.0.3", + "npm-pick-manifest": "^6.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^1.1.1", + "semver": "^7.3.2", + "unique-filename": "^1.1.1", + "which": "^2.0.2" }, "dependencies": { "mkdirp": { @@ -3342,9 +3713,95 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, + "@npmcli/installed-package-contents": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-1.0.5.tgz", + "integrity": "sha512-aKIwguaaqb6ViwSOFytniGvLPb9SMCUm39TgM3SfUo7n0TxUMbwoXfpwyvQ4blm10lzbAwTsvjr7QZ85LvTi4A==", + "dev": true, + "requires": { + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1", + "read-package-json-fast": "^1.1.1", + "readdir-scoped-modules": "^1.1.0" + } + }, + "@npmcli/move-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.0.tgz", + "integrity": "sha512-Iv2iq0JuyYjKeFkSR4LPaCdDZwlGK9X2cP/01nJcp3yMJ1FjNd9vpiEYvLUgzBxKPg2SFmaOhizoQsPc0LWeOQ==", + "dev": true, + "requires": { + "mkdirp": "^1.0.4", + "rimraf": "^2.7.1" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "@npmcli/node-gyp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-1.0.1.tgz", + "integrity": "sha512-pBqoKPWmuk9iaEcXlLBVRIA6I1kG9JiICU+sG0NuD6NAR461F+02elHJS4WkQxHW2W5rnsfvP/ClKwmsZ9RaaA==", + "dev": true + }, + "@npmcli/promise-spawn": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz", + "integrity": "sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg==", + "dev": true, + "requires": { + "infer-owner": "^1.0.4" + } + }, + "@npmcli/run-script": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-1.8.1.tgz", + "integrity": "sha512-G8c86g9cQHyRINosIcpovzv0BkXQc3urhL1ORf3KTe4TS4UBsg2O4Z2feca/W3pfzdHEJzc83ETBW4aKbb3SaA==", + "dev": true, + "requires": { + "@npmcli/node-gyp": "^1.0.0", + "@npmcli/promise-spawn": "^1.3.0", + "infer-owner": "^1.0.4", + "node-gyp": "^7.1.0", + "puka": "^1.0.1", + "read-package-json-fast": "^1.1.3" + } + }, "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -3400,123 +3857,46 @@ "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" }, "@schematics/angular": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-11.0.4.tgz", - "integrity": "sha512-LwBD9TIoLy9XqqInJvlN4BHtPyJExyeorNiOp6rXb/wafuDbvZ+9kY9GWZTY1auVo5PNKqErfxr74ydA3FFb9g==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-11.1.2.tgz", + "integrity": "sha512-ZhaB/QBwfWsvZYJplLH8VK/7vnFpUbk1nptjC106K/I38xlmWdB4pStLJK94eyJk0KlItnsPvE0a9KuLPKA/Ow==", "dev": true, "requires": { - "@angular-devkit/core": "11.0.4", - "@angular-devkit/schematics": "11.0.4", - "jsonc-parser": "2.3.1" - }, - "dependencies": { - "@angular-devkit/core": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.0.4.tgz", - "integrity": "sha512-LgTvhZ3Ycz0QvNAH/zO1rpQQDn2JN8u9/Awy1gW/XeCC3FYmxeOj/2JCFzlKah3wJv16nMqro5WTppHt8Y++PA==", - "dev": true, - "requires": { - "ajv": "6.12.6", - "fast-json-stable-stringify": "2.1.0", - "magic-string": "0.25.7", - "rxjs": "6.6.3", - "source-map": "0.7.3" - } - }, - "@angular-devkit/schematics": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-11.0.4.tgz", - "integrity": "sha512-fFC7qW9A1bFAZgpCfkezBA4WCRzfVFgOzwPpyt65rgSrzw0+EeHjcrUIcXlhyOXAFrTHtA9oLCfEeSjSx5HBEA==", - "dev": true, - "requires": { - "@angular-devkit/core": "11.0.4", - "ora": "5.1.0", - "rxjs": "6.6.3" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - } + "@angular-devkit/core": "11.1.2", + "@angular-devkit/schematics": "11.1.2", + "jsonc-parser": "3.0.0" } }, "@schematics/update": { - "version": "0.1100.4", - "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.1100.4.tgz", - "integrity": "sha512-YwFtgxCQQkYC89IC7dfshyGr0roE6bpp5HgpQLdS/AOjHeZKo7/SPdM0W4ddB+Fml1Fo6v4eFG/Ia9oR7qNv1A==", + "version": "0.1101.2", + "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.1101.2.tgz", + "integrity": "sha512-WwMsIkhR3hq7gvfB5HsuTK2Sz9iZmpz0/AiFYRJbX+mXL/KgONcridyorW45Dg1Q2sRXVGiAUxWsQYzjmeLO7g==", "dev": true, "requires": { - "@angular-devkit/core": "11.0.4", - "@angular-devkit/schematics": "11.0.4", + "@angular-devkit/core": "11.1.2", + "@angular-devkit/schematics": "11.1.2", "@yarnpkg/lockfile": "1.1.0", - "ini": "1.3.5", + "ini": "2.0.0", "npm-package-arg": "^8.0.0", - "pacote": "9.5.12", - "semver": "7.3.2", + "pacote": "11.1.14", + "semver": "7.3.4", "semver-intersect": "1.4.0" }, "dependencies": { - "@angular-devkit/core": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-11.0.4.tgz", - "integrity": "sha512-LgTvhZ3Ycz0QvNAH/zO1rpQQDn2JN8u9/Awy1gW/XeCC3FYmxeOj/2JCFzlKah3wJv16nMqro5WTppHt8Y++PA==", - "dev": true, - "requires": { - "ajv": "6.12.6", - "fast-json-stable-stringify": "2.1.0", - "magic-string": "0.25.7", - "rxjs": "6.6.3", - "source-map": "0.7.3" - } - }, - "@angular-devkit/schematics": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-11.0.4.tgz", - "integrity": "sha512-fFC7qW9A1bFAZgpCfkezBA4WCRzfVFgOzwPpyt65rgSrzw0+EeHjcrUIcXlhyOXAFrTHtA9oLCfEeSjSx5HBEA==", - "dev": true, - "requires": { - "@angular-devkit/core": "11.0.4", - "ora": "5.1.0", - "rxjs": "6.6.3" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } + "ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, @@ -3539,6 +3919,12 @@ "unist-util-find-all-after": "^3.0.2" } }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, "@types/bytebuffer": { "version": "5.0.41", "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.41.tgz", @@ -3554,6 +3940,24 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/component-emitter": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz", + "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==", + "dev": true + }, + "@types/cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg==", + "dev": true + }, + "@types/cors": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.9.tgz", + "integrity": "sha512-zurD1ibz21BRlAOIKP8yhrxlqKx6L9VCwkB5kMiP6nZAhoF5MvC7qS1qPA7nRcr1GJolfkQC7/EAL4hdYejLtg==", + "dev": true + }, "@types/file-saver": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.1.tgz", @@ -3575,9 +3979,9 @@ "integrity": "sha512-6PjMFKl13cgB4kRdYtvyjKl8VVa0PXS2IdVxHhQ8GEKbxBkyJtSbaIeK1eZGjDKN7dvUh4vkOvU9FMwYNv4GQQ==" }, "@types/jasmine": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.6.2.tgz", - "integrity": "sha512-AzfesNFLvOs6Q1mHzIsVJXSeUnqVh4ZHG8ngygKJfbkcSLwzrBVm/LKa+mR8KrOfnWtUL47112gde1MC0IXqpQ==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.6.3.tgz", + "integrity": "sha512-5QKAG8WfC9XrOgYLXPrxv1G2IIUE6zDyzTWamhNWJO0LqPRUbZ0q0zGHDhDJ7MpFloUuyME/jpBIdPjq3/P3jA==", "dev": true }, "@types/jasminewd2": { @@ -3590,9 +3994,9 @@ } }, "@types/json-schema": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", - "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", "dev": true }, "@types/long": { @@ -3622,9 +4026,9 @@ "dev": true }, "@types/node": { - "version": "14.14.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.13.tgz", - "integrity": "sha512-vbxr0VZ8exFMMAjCW8rJwaya0dMCDyYW2ZRdTyjtrCvJoENMpdUHOT/eTzvgyA5ZnqRZ/sI0NwqAxNHKYokLJQ==" + "version": "14.14.22", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.22.tgz", + "integrity": "sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw==" }, "@types/normalize-package-data": { "version": "2.4.0", @@ -3871,16 +4275,6 @@ "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", "dev": true }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, "abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -3924,12 +4318,6 @@ "integrity": "sha512-/9aQCnQHF+0IiCl0qhXoK7qs//SwYE7zX8lsr/DNk1BRAHYxeLZPL4pguwK29gUEqasYQjqPtEpDRSWEkdHn9g==", "dev": true }, - "after": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", - "dev": true - }, "agent-base": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", @@ -3940,12 +4328,25 @@ } }, "agentkeepalive": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz", - "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.1.3.tgz", + "integrity": "sha512-wn8fw19xKZwdGPO47jivonaHRTd+nGOMP1z11sgGeQzDy2xd5FG0R67dIMcKHDE2cJ5y+YXV30XVGUBPRSY7Hg==", "dev": true, "requires": { + "debug": "^4.1.0", + "depd": "^1.1.2", "humanize-ms": "^1.2.1" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + } } }, "aggregate-error": { @@ -3997,9 +4398,9 @@ } }, "angularx-qrcode": { - "version": "10.0.11", - "resolved": "https://registry.npmjs.org/angularx-qrcode/-/angularx-qrcode-10.0.11.tgz", - "integrity": "sha512-sbtqdqAboEFNoyxgG4FQYPZDzwX9TlICT2mLpsC/Se3OuT+HntW56q8E/i1BL1fJhx7zt0JJR7bc7LfofUeAlQ==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/angularx-qrcode/-/angularx-qrcode-11.0.0.tgz", + "integrity": "sha512-qg6g288LO9daqBP5GCHewy9W0IMW7jDMEaAiklA1za0UhjCj6VH1Agydr4JVp7RMkw1LsLapFhWsVSYqrWaERA==", "requires": { "qrcode": "1.4.2", "tslib": "^2.0.0" @@ -4182,18 +4583,18 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, - "arraybuffer.slice": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", - "dev": true - }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, "ascli": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", @@ -4353,29 +4754,17 @@ } }, "babel-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", - "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz", + "integrity": "sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g==", "dev": true, "requires": { - "find-cache-dir": "^2.1.0", + "find-cache-dir": "^3.3.1", "loader-utils": "^1.4.0", - "mkdirp": "^0.5.3", - "pify": "^4.0.1", + "make-dir": "^3.1.0", "schema-utils": "^2.6.5" }, "dependencies": { - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, "json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -4407,12 +4796,6 @@ "object.assign": "^4.1.0" } }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", - "dev": true - }, "bail": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", @@ -4480,9 +4863,9 @@ } }, "base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", + "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=", "dev": true }, "base64-js": { @@ -4512,15 +4895,6 @@ "tweetnacl": "^0.14.3" } }, - "better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", - "dev": true, - "requires": { - "callsite": "1.0.0" - } - }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -4543,11 +4917,16 @@ "file-uri-to-path": "1.0.0" } }, - "blob": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", - "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", - "dev": true + "bl": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", + "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } }, "blocking-proxy": { "version": "1.0.1", @@ -4777,14 +5156,13 @@ } }, "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, "buffer-from": { @@ -4910,13 +5288,13 @@ } }, "call-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", - "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dev": true, "requires": { "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.0" + "get-intrinsic": "^1.0.2" } }, "caller-callsite": { @@ -4937,12 +5315,6 @@ "caller-callsite": "^2.0.0" } }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", - "dev": true - }, "callsites": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", @@ -5087,9 +5459,9 @@ } }, "circular-dependency-plugin": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.0.tgz", - "integrity": "sha512-7p4Kn/gffhQaavNfyDFg7LS5S/UT1JAjyGd4UqR2+jzoYF02eDkj0Ec3+48TsIa4zghjLY87nQHIh/ecK9qLdw==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz", + "integrity": "sha512-g38K9Cm5WRwlaH6g03B9OEz/0qRizI+2I7n+Gz+L5DxXJAPAiWQvwlYNm1V1jkdpUv95bOe/ASm2vfi/G560jQ==", "dev": true }, "class-utils": { @@ -5335,24 +5707,12 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, - "component-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", - "dev": true - }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true }, - "component-inherit": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", - "dev": true - }, "compose-function": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz", @@ -5562,6 +5922,15 @@ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", "dev": true }, + "copy-anything": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.1.tgz", + "integrity": "sha512-lA57e7viQHOdPQcrytv5jFeudZZOXuyk47lZym279FiDQ8jeZomXiGuVf6ffMKkJ+3TIai3J1J3yi6M+/4U35g==", + "dev": true, + "requires": { + "is-what": "^3.7.1" + } + }, "copy-concurrently": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", @@ -5583,9 +5952,9 @@ "dev": true }, "copy-webpack-plugin": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.2.1.tgz", - "integrity": "sha512-VH2ZTMIBsx4p++Lmpg77adZ0KUyM5gFR/9cuTrbneNnJlcQXUFvsNariPqq2dq2kV3F2skHiDGPQCyKWy1+U0Q==", + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.3.2.tgz", + "integrity": "sha512-MgJ1uouLIbDg4ST1GzqrGQyKoXY5iPqi6fghFqarijam7FQcBa/r6Rg0VkoIuzx75Xq8iAMghyOueMkWUQ5OaA==", "dev": true, "requires": { "cacache": "^15.0.5", @@ -5646,44 +6015,44 @@ } }, "core-js": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", - "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==", + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.2.tgz", + "integrity": "sha512-FfApuSRgrR6G5s58casCBd9M2k+4ikuu4wbW6pJyYU7bd9zvFc9qf7vr5xmrZOhT9nn+8uwlH1oRR9jTnFoA3A==", "dev": true }, "core-js-compat": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.8.1.tgz", - "integrity": "sha512-a16TLmy9NVD1rkjUGbwuyWkiDoN0FDpAwrfLONvHFQx0D9k7J9y0srwMT8QP/Z6HE3MIFaVynEeYwZwPX1o5RQ==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.8.3.tgz", + "integrity": "sha512-1sCb0wBXnBIL16pfFG1Gkvei6UzvKyTNYpiC41yrdjEv0UoJoq9E/abTMzyYJ6JpTkAj15dLjbqifIzEBDVvog==", "dev": true, "requires": { - "browserslist": "^4.15.0", + "browserslist": "^4.16.1", "semver": "7.0.0" }, "dependencies": { "browserslist": { - "version": "4.16.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.0.tgz", - "integrity": "sha512-/j6k8R0p3nxOC6kx5JGAxsnhc9ixaWJfYc+TNTzxg6+ARaESAvQGV7h0uNOB4t+pLQJZWzcrMxXOxjgsCj3dqQ==", + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", + "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001165", + "caniuse-lite": "^1.0.30001181", "colorette": "^1.2.1", - "electron-to-chromium": "^1.3.621", + "electron-to-chromium": "^1.3.649", "escalade": "^3.1.1", - "node-releases": "^1.1.67" + "node-releases": "^1.1.70" } }, "caniuse-lite": { - "version": "1.0.30001165", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001165.tgz", - "integrity": "sha512-8cEsSMwXfx7lWSUMA2s08z9dIgsnR5NAqjXP23stdsU3AUWkCr/rr4s4OFtHXn5XXr6+7kam3QFVoYyXNPdJPA==", + "version": "1.0.30001181", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001181.tgz", + "integrity": "sha512-m5ul/ARCX50JB8BSNM+oiPmQrR5UmngaQ3QThTTp5HcIIQGP/nPBs82BYLE+tigzm3VW+F4BJIhUyaVtEweelQ==", "dev": true }, "electron-to-chromium": { - "version": "1.3.625", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.625.tgz", - "integrity": "sha512-CsLk/r0C9dAzVPa9QF74HIXduxaucsaRfqiOYvIv2PRhvyC6EOqc/KbpgToQuDVgPf3sNAFZi3iBu4vpGOwGag==", + "version": "1.3.649", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.649.tgz", + "integrity": "sha512-ojGDupQ3UMkvPWcTICe4JYe17+o9OLiFMPoduoR72Zp2ILt1mRVeqnxBEd6s/ptekrnsFU+0A4lStfBe/wyG/A==", "dev": true }, "escalade": { @@ -5693,9 +6062,9 @@ "dev": true }, "node-releases": { - "version": "1.1.67", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.67.tgz", - "integrity": "sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg==", + "version": "1.1.70", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.70.tgz", + "integrity": "sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==", "dev": true }, "semver": { @@ -5802,6 +6171,76 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "critters": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.6.tgz", + "integrity": "sha512-NUB3Om7tkf+XWi9+2kJ2A3l4/tHORDI1UT+nHxUqay2B/tJvMpiXcklDDLBH3fPn9Pe23uu0we/08Ukjy4cLCQ==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "css": "^3.0.0", + "parse5": "^6.0.1", + "parse5-htmlparser2-tree-adapter": "^6.0.1", + "pretty-bytes": "^5.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -5835,15 +6274,14 @@ } }, "css": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", - "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", + "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", "dev": true, "requires": { - "inherits": "^2.0.3", + "inherits": "^2.0.4", "source-map": "^0.6.1", - "source-map-resolve": "^0.5.2", - "urix": "^0.1.0" + "source-map-resolve": "^0.6.0" } }, "css-color-names": { @@ -5863,31 +6301,65 @@ } }, "css-loader": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-4.3.0.tgz", - "integrity": "sha512-rdezjCjScIrsL8BSYszgT4s476IcNKt6yX69t0pHjJVnPUTDpn4WfIpDQTN3wCJvUvfsz/mFjuGOekf3PY3NUg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.0.1.tgz", + "integrity": "sha512-cXc2ti9V234cq7rJzFKhirb2L2iPy8ZjALeVJAozXYz9te3r4eqLSixNAbMDJSgJEQywqXzs8gonxaboeKqwiw==", "dev": true, "requires": { - "camelcase": "^6.0.0", + "camelcase": "^6.2.0", "cssesc": "^3.0.0", - "icss-utils": "^4.1.1", + "icss-utils": "^5.0.0", "loader-utils": "^2.0.0", - "postcss": "^7.0.32", - "postcss-modules-extract-imports": "^2.0.0", - "postcss-modules-local-by-default": "^3.0.3", - "postcss-modules-scope": "^2.2.0", - "postcss-modules-values": "^3.0.0", + "postcss": "^8.1.4", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.1.0", - "schema-utils": "^2.7.1", + "schema-utils": "^3.0.0", "semver": "^7.3.2" }, "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "camelcase": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true }, + "postcss": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.4.tgz", + "integrity": "sha512-kRFftRoExRVXZlwUuay9iC824qmXPcQQVzAjbCCgjpXnkdMCJYBu2gTwAaFBzv8ewND6O8xFb3aELmEkh9zTzg==", + "dev": true, + "requires": { + "colorette": "^1.2.1", + "nanoid": "^3.1.20", + "source-map": "^0.6.1" + } + }, + "schema-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, "semver": { "version": "7.3.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", @@ -5906,6 +6378,33 @@ "dev": true, "requires": { "css": "^2.0.0" + }, + "dependencies": { + "css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + } } }, "css-select": { @@ -6146,6 +6645,12 @@ "ms": "^2.1.1" } }, + "debuglog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=", + "dev": true + }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", @@ -6357,6 +6862,16 @@ "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", "dev": true }, + "dezalgo": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", + "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", + "dev": true, + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, "di": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", @@ -6623,6 +7138,7 @@ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "dev": true, + "optional": true, "requires": { "iconv-lite": "^0.6.2" }, @@ -6632,6 +7148,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", "dev": true, + "optional": true, "requires": { "safer-buffer": ">= 2.1.2 < 3.0.0" } @@ -6648,102 +7165,60 @@ } }, "engine.io": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.2.tgz", - "integrity": "sha512-b4Q85dFkGw+TqgytGPrGgACRUhsdKc9S9ErRAXpPGy/CXKs4tYoHDkvIRdsseAF7NjfVwjRFIn6KTnbw7LwJZg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.0.tgz", + "integrity": "sha512-vW7EAtn0HDQ4MtT5QbmCHF17TaYLONv2/JwdYsq9USPRZVM4zG7WB3k0Nc321z8EuSOlhGokrYlYx4176QhD0A==", "dev": true, "requires": { "accepts": "~1.3.4", "base64id": "2.0.0", - "cookie": "0.3.1", - "debug": "~4.1.0", - "engine.io-parser": "~2.2.0", - "ws": "^7.1.2" + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~4.0.0", + "ws": "~7.4.2" }, "dependencies": { "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", "dev": true }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "ws": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", - "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==", + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz", + "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==", "dev": true } } }, - "engine.io-client": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.3.tgz", - "integrity": "sha512-0NGY+9hioejTEJCaSJZfWZLk4FPI9dN+1H1C4+wj2iuFba47UgZbJzfWs4aNFajnX/qAaYKbe2lLTfEEWzCmcw==", - "dev": true, - "requires": { - "component-emitter": "~1.3.0", - "component-inherit": "0.0.3", - "debug": "~4.1.0", - "engine.io-parser": "~2.2.0", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "~6.1.0", - "xmlhttprequest-ssl": "~1.5.4", - "yeast": "0.1.2" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ws": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", - "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - } - } - }, "engine.io-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz", - "integrity": "sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz", + "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==", "dev": true, "requires": { - "after": "0.8.2", - "arraybuffer.slice": "~0.0.7", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.5", - "has-binary2": "~1.0.2" + "base64-arraybuffer": "0.1.4" } }, "enhanced-resolve": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.3.1.tgz", - "integrity": "sha512-G1XD3MRGrGfNcf6Hg0LVZG7GIKcYkbfHa5QMxt1HDUTdYoXH0JR1xXyg+MaKLF73E9A27uWNVxvFivNRYeUB6w==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.6.0.tgz", + "integrity": "sha512-C3GGDfFZmqUa21o10YRKbZN60DPl0HyXKXxoEnQMWso9u7KMU23L7CBHfr/rVxORddY/8YQZaU2MZ1ewTS8Pcw==", "dev": true, "requires": { "graceful-fs": "^4.2.4", - "tapable": "^2.0.0" + "tapable": "^2.2.0" }, "dependencies": { "graceful-fs": { @@ -6766,6 +7241,12 @@ "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", "dev": true }, + "env-paths": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz", + "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==", + "dev": true + }, "err-code": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", @@ -6773,9 +7254,9 @@ "dev": true }, "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", "dev": true, "requires": { "prr": "~1.0.1" @@ -6791,23 +7272,25 @@ } }, "es-abstract": { - "version": "1.18.0-next.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", - "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "version": "1.18.0-next.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.2.tgz", + "integrity": "sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw==", "dev": true, "requires": { + "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2", "has": "^1.0.3", "has-symbols": "^1.0.1", "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.0", + "is-negative-zero": "^2.0.1", "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", + "object-inspect": "^1.9.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.3", + "string.prototype.trimstart": "^1.0.3" } }, "es-to-primitive": { @@ -7254,9 +7737,9 @@ "dev": true }, "fast-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -7265,60 +7748,6 @@ "merge2": "^1.3.0", "micromatch": "^4.0.2", "picomatch": "^2.2.1" - }, - "dependencies": { - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - } } }, "fast-json-stable-stringify": { @@ -7349,9 +7778,9 @@ } }, "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", "dev": true, "requires": { "websocket-driver": ">=0.5.1" @@ -7382,9 +7811,9 @@ } }, "file-loader": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.1.1.tgz", - "integrity": "sha512-Klt8C4BjWSXYQAfhpYYkG4qHNTna4toMHEbWrI5IuVoxbU6uiDKeKAP99R8mmbJi3lvewn/jQBOgU4+NS3tDQw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", "dev": true, "requires": { "loader-utils": "^2.0.0", @@ -7478,48 +7907,6 @@ "commondir": "^1.0.1", "make-dir": "^3.0.2", "pkg-dir": "^4.1.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } } }, "find-up": { @@ -7560,9 +7947,9 @@ }, "dependencies": { "flatted": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", - "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, "rimraf": { @@ -7662,6 +8049,12 @@ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", "dev": true }, + "fraction.js": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.13.tgz", + "integrity": "sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA==", + "dev": true + }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -7816,12 +8209,6 @@ "wide-align": "^1.1.0" } }, - "genfun": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz", - "integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==", - "dev": true - }, "gensync": { "version": "1.0.0-beta.1", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", @@ -7834,9 +8221,9 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-intrinsic": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz", - "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.0.tgz", + "integrity": "sha512-M11rgtQp5GZMZzDL7jLTNxbDfurpzuau5uqRWDPvlHjfvg3TdScAZo96GLvhMjImrmR8uAt0FS2RLoMrfWGKlg==", "dev": true, "requires": { "function-bind": "^1.1.1", @@ -7923,9 +8310,9 @@ "dev": true }, "globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz", + "integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==", "dev": true, "requires": { "array-union": "^2.1.0", @@ -7960,9 +8347,9 @@ } }, "google-proto-files": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/google-proto-files/-/google-proto-files-2.3.0.tgz", - "integrity": "sha512-A2UMuWes/9dgEWV8jr+KBM95LyyJQpHMlGbBV0wFIuJs1VRlgpPWR1m39fat1J2nKLYPyfhi42TTnEOnGWopWg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/google-proto-files/-/google-proto-files-2.4.0.tgz", + "integrity": "sha512-M5u56EsADOnplBUHTBzqBcCtPNPoGtBBXefjtA7mt3KDsOnlRM75fwrW2rsPS3Am2vrf9I0/NlI0E3nKWo/Ipg==", "requires": { "protobufjs": "^6.8.0", "walkdir": "^0.4.0" @@ -8056,29 +8443,6 @@ "ansi-regex": "^2.0.0" } }, - "has-binary2": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", - "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", - "dev": true, - "requires": { - "isarray": "2.0.1" - }, - "dependencies": { - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true - } - } - }, - "has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", - "dev": true - }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -8248,9 +8612,9 @@ "dev": true }, "html-entities": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.3.tgz", - "integrity": "sha512-/VulV3SYni1taM7a4RMdceqzJWR39gpZHjBwUnsCFKWV/GJkD14CJ5F7eWcZozmHJK0/f/H5U3b3SiPkuvxMgg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz", + "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==", "dev": true }, "html-escaper": { @@ -8280,9 +8644,9 @@ } }, "http-cache-semantics": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", - "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", "dev": true }, "http-deceiver": { @@ -8312,6 +8676,12 @@ } } }, + "http-parser-js": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", + "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==", + "dev": true + }, "http-proxy": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", @@ -8324,29 +8694,33 @@ } }, "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "dev": true, "requires": { - "agent-base": "4", - "debug": "3.1.0" + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" }, "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "requires": { - "ms": "2.0.0" + "debug": "4" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } } } }, @@ -8492,13 +8866,10 @@ } }, "icss-utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", - "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", - "dev": true, - "requires": { - "postcss": "^7.0.14" - } + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true }, "ieee754": { "version": "1.2.1", @@ -8571,6 +8942,17 @@ "requires": { "pkg-dir": "^3.0.0", "resolve-cwd": "^2.0.0" + }, + "dependencies": { + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + } } }, "imurmurhash": { @@ -8591,12 +8973,6 @@ "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", "dev": true }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true - }, "infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", @@ -8618,9 +8994,9 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "inquirer": { "version": "7.3.3", @@ -8832,9 +9208,9 @@ "dev": true }, "is-callable": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", - "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", "dev": true }, "is-color-stop": { @@ -8964,6 +9340,12 @@ "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "dev": true }, + "is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=", + "dev": true + }, "is-negative-zero": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", @@ -9097,6 +9479,12 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "is-what": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.12.0.tgz", + "integrity": "sha512-2ilQz5/f/o9V7WRWJQmpFYNmQFZ9iM+OXRonZKcYgTkCzjb949Vi4h282PD1UfmgHk666rcWonbRJ++KI41VGw==", + "dev": true + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -9307,9 +9695,9 @@ "dev": true }, "jest-worker": { - "version": "26.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.5.0.tgz", - "integrity": "sha512-kTw66Dn4ZX7WpjZ7T/SUDgRhapFRKWmisVAF0Rv4Fu8SLFD7eLbqpLvbxVqYhSgaWa7I+bW7pHnbyfNsH6stug==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, "requires": { "@types/node": "*", @@ -9408,9 +9796,9 @@ } }, "jsonc-parser": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.3.1.tgz", - "integrity": "sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", + "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", "dev": true }, "jsonfile": { @@ -9485,9 +9873,9 @@ } }, "karma": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/karma/-/karma-5.2.3.tgz", - "integrity": "sha512-tHdyFADhVVPBorIKCX8A37iLHxc6RBRphkSoQ+MLKdAtFn1k97tD8WUGi1KlEtDZKL3hui0qhsY9HXUfSNDYPQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.0.3.tgz", + "integrity": "sha512-dmiLQdsNAvnbV1G6VvUK7Cl5xpwiMisZNT8MjBtOo49jKlnZSWLxQIemuLT8sGSzvx5IGgMfMQEtf/CALiUEVQ==", "dev": true, "requires": { "body-parser": "^1.19.0", @@ -9508,11 +9896,11 @@ "qjobs": "^1.2.0", "range-parser": "^1.2.1", "rimraf": "^3.0.2", - "socket.io": "^2.3.0", + "socket.io": "^3.0.4", "source-map": "^0.6.1", "tmp": "0.2.1", - "ua-parser-js": "0.7.22", - "yargs": "^15.3.1" + "ua-parser-js": "^0.7.23", + "yargs": "^16.1.1" }, "dependencies": { "ansi-regex": { @@ -9522,46 +9910,23 @@ "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "chokidar": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", - "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" - } - }, "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "wrap-ansi": "^7.0.0" } }, "color-convert": { @@ -9579,15 +9944,11 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true }, "graceful-fs": { "version": "4.2.4", @@ -9602,26 +9963,11 @@ "dev": true }, "mime": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", - "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.0.tgz", + "integrity": "sha512-ft3WayFSFUVBuJj7BMLKAQcSlItKtfjsKDDsii3rqFDAZ7t11zRe8ASw/GlmivGwVUYtwkQrxiGGpL6gFvB0ag==", "dev": true }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -9661,9 +10007,9 @@ } }, "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -9672,39 +10018,31 @@ } }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", "dev": true }, "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" } }, "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true } } }, @@ -9787,21 +10125,46 @@ } }, "less": { - "version": "3.12.2", - "resolved": "https://registry.npmjs.org/less/-/less-3.12.2.tgz", - "integrity": "sha512-+1V2PCMFkL+OIj2/HrtrvZw0BC0sYLMICJfbQjuj/K8CEnlrFX6R5cKKgzzttsZDHyxQNL1jqMREjKN3ja/E3Q==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/less/-/less-4.1.0.tgz", + "integrity": "sha512-w1Ag/f34g7LwtQ/sMVSGWIyZx+gG9ZOAEtyxeX1fG75is6BMyC2lD5kG+1RueX7PkAvlQBm2Lf2aN2j0JbVr2A==", "dev": true, "requires": { + "copy-anything": "^2.0.1", "errno": "^0.1.1", "graceful-fs": "^4.1.2", "image-size": "~0.5.0", "make-dir": "^2.1.0", "mime": "^1.4.1", - "native-request": "^1.0.5", + "needle": "^2.5.2", + "parse-node-version": "^1.0.1", "source-map": "~0.6.0", "tslib": "^1.10.0" }, "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "optional": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "needle": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz", + "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==", + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -9811,9 +10174,9 @@ } }, "less-loader": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-7.0.2.tgz", - "integrity": "sha512-7MKlgjnkCf63E3Lv6w2FvAEgLMx3d/tNBExITcanAq7ys5U8VPWT3F6xcRjYmdNfkoQ9udoVFb1r2azSiTnD6w==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-7.3.0.tgz", + "integrity": "sha512-Mi8915g7NMaLlgi77mgTTQvK022xKRQBIVDSyfl3ErTuBhmZBQab0mjeJjNNqGbdR+qrfTleKXqbGI4uEFavxg==", "dev": true, "requires": { "klona": "^2.0.4", @@ -9847,9 +10210,9 @@ } }, "license-webpack-plugin": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-2.3.1.tgz", - "integrity": "sha512-yhqTmlYIEpZWA122lf6E0G8+rkn0AzoQ1OpzUKKs/lXUqG1plmGnwmkuuPlfggzJR5y6DLOdot/Tv00CC51CeQ==", + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-2.3.11.tgz", + "integrity": "sha512-0iVGoX5vx0WDy8dmwTTpOOMYiGqILyUbDeVMFH52AjgBlS58lHwOlFMSoqg5nY8Kxl6+FRKyUZY/UdlQaOyqDw==", "dev": true, "requires": { "@types/webpack-sources": "^0.1.5", @@ -10012,9 +10375,9 @@ }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -10058,13 +10421,20 @@ } }, "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "make-error": { @@ -10074,76 +10444,55 @@ "dev": true }, "make-fetch-happen": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz", - "integrity": "sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag==", + "version": "8.0.13", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-8.0.13.tgz", + "integrity": "sha512-rQ5NijwwdU8tIaBrpTtSVrNCcAJfyDRcKBC76vOQlyJX588/88+TE+UpjWl4BgG7gCkp29wER7xcRqkeg+x64Q==", "dev": true, "requires": { - "agentkeepalive": "^3.4.1", - "cacache": "^12.0.0", - "http-cache-semantics": "^3.8.1", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "node-fetch-npm": "^2.0.2", + "agentkeepalive": "^4.1.3", + "cacache": "^15.0.5", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", "promise-retry": "^1.1.1", - "socks-proxy-agent": "^4.0.0", - "ssri": "^6.0.0" + "socks-proxy-agent": "^5.0.0", + "ssri": "^8.0.0" }, "dependencies": { - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" + "debug": "4" } }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "yallist": "^3.0.2" + "ms": "2.1.2" } }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", "dev": true, "requires": { - "figgy-pudding": "^3.5.1" + "agent-base": "6", + "debug": "4" } - }, - "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true } } }, @@ -10186,35 +10535,36 @@ } }, "mdast-util-from-markdown": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.1.tgz", - "integrity": "sha512-qJXNcFcuCSPqUF0Tb0uYcFDIq67qwB3sxo9RPdf9vG8T90ViKnksFqdB/Coq2a7sTnxL/Ify2y7aIQXDkQFH0w==", + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.4.tgz", + "integrity": "sha512-jj891B5pV2r63n2kBTFh8cRI2uR9LQHsXG1zSDqfhXkIlDzrTcIlbB5+5aaYEkl8vOPIOPLf8VT7Ere1wWTMdw==", "dev": true, "requires": { "@types/mdast": "^3.0.0", - "mdast-util-to-string": "^1.0.0", - "micromark": "~2.10.0", - "parse-entities": "^2.0.0" + "mdast-util-to-string": "^2.0.0", + "micromark": "~2.11.0", + "parse-entities": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" } }, "mdast-util-to-markdown": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.5.3.tgz", - "integrity": "sha512-sr8q7fQJ1xoCqZSXW6dO/MYu2Md+a4Hfk9uO+XHCfiBhVM0EgWtfAV7BuN+ff6otUeu2xDyt1o7vhZGwOG3+BA==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.2.tgz", + "integrity": "sha512-iRczns6WMvu0hUw02LXsPDJshBIwtUPbvHBWo19IQeU0YqmzlA8Pd30U8V7uiI0VPkxzS7A/NXBXH6u+HS87Zg==", "dev": true, "requires": { "@types/unist": "^2.0.0", "longest-streak": "^2.0.0", - "mdast-util-to-string": "^1.0.0", + "mdast-util-to-string": "^2.0.0", "parse-entities": "^2.0.0", "repeat-string": "^1.0.0", "zwitch": "^1.0.0" } }, "mdast-util-to-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", - "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", "dev": true }, "mdn-data": { @@ -10272,13 +10622,14 @@ } }, "meow": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.0.0.tgz", - "integrity": "sha512-nbsTRz2fwniJBFgUkcdISq8y/q9n9VbiHYbfwklFh5V4V2uAcxtKQkDc0yCLPM/kP0d+inZBewn3zJqewHE7kg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", "dev": true, "requires": { "@types/minimist": "^1.2.0", "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", "decamelize-keys": "^1.1.0", "hard-rejection": "^2.1.0", "minimist-options": "4.1.0", @@ -10322,10 +10673,13 @@ } }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "type-fest": { "version": "0.18.1", @@ -10375,9 +10729,9 @@ "dev": true }, "micromark": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.10.1.tgz", - "integrity": "sha512-fUuVF8sC1X7wsCS29SYQ2ZfIZYbTymp0EYr6sab3idFjigFFjGa5UwoniPlV9tAgntjuapW1t9U+S0yDYeGKHQ==", + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.2.tgz", + "integrity": "sha512-IXuP76p2uj8uMg4FQc1cRE7lPCLsfAXuEfdjtdO55VRiFO1asrCSQ5g43NmPqFtRwzEnEhafRVzn2jg0UiKArQ==", "dev": true, "requires": { "debug": "^4.0.0", @@ -10457,9 +10811,9 @@ "dev": true }, "mini-css-extract-plugin": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.2.1.tgz", - "integrity": "sha512-G3yw7/TQaPfkuiR73MDcyiqhyP8SnbmLhUbpC76H+wtQxA6wfKhMCQOCb6wnPK0dQbjORAeOILQqEesg4/wF7A==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.3.3.tgz", + "integrity": "sha512-7lvliDSMiuZc81kI+5/qxvn47SCM7BehXex3f2c6l/pR3Goj58IQxZh9nuPQ3AkGQgoETyXuIqLDaO5Oa0TyBw==", "dev": true, "requires": { "loader-utils": "^2.0.0", @@ -10564,6 +10918,18 @@ "minipass": "^3.0.0" } }, + "minipass-fetch": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.3.3.tgz", + "integrity": "sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ==", + "dev": true, + "requires": { + "encoding": "^0.1.12", + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" + } + }, "minipass-flush": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", @@ -10573,6 +10939,16 @@ "minipass": "^3.0.0" } }, + "minipass-json-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", + "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", + "dev": true, + "requires": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + } + }, "minipass-pipeline": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", @@ -10582,6 +10958,15 @@ "minipass": "^3.0.0" } }, + "minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, "minizlib": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", @@ -10690,6 +11075,12 @@ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" }, + "nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -10709,13 +11100,6 @@ "to-regex": "^3.0.1" } }, - "native-request": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/native-request/-/native-request-1.0.8.tgz", - "integrity": "sha512-vU2JojJVelUGp6jRcLwToPoWGxSx23z/0iX+I77J3Ht17rf2INGjrhOoQnjVo60nQd8wVsgzKkPfRXBiVdD2ag==", - "dev": true, - "optional": true - }, "needle": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.0.tgz", @@ -10758,23 +11142,112 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, - "node-fetch-npm": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz", - "integrity": "sha512-iOuIQDWDyjhv9qSDrj9aq/klt6F9z1p2otB3AV7v3zBDcL/x+OfGsvGQZZCcMZbUf4Ujw1xGNQkjvGnVT22cKg==", - "dev": true, - "requires": { - "encoding": "^0.1.11", - "json-parse-better-errors": "^1.0.0", - "safe-buffer": "^5.1.1" - } - }, "node-forge": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", "dev": true }, + "node-gyp": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", + "dev": true, + "requires": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" + }, + "dependencies": { + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "node-libs-browser": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", @@ -10806,6 +11279,17 @@ "vm-browserify": "^1.0.1" }, "dependencies": { + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -11015,9 +11499,9 @@ }, "dependencies": { "hosted-git-info": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.7.tgz", - "integrity": "sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz", + "integrity": "sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -11035,13 +11519,14 @@ } }, "npm-packlist": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", - "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-2.1.4.tgz", + "integrity": "sha512-Qzg2pvXC9U4I4fLnUrBmcIT4x0woLtUgxUi9eC+Zrcv1Xx5eamytGAfbDWQ67j7xOcQ2VW1I3su9smVTIdu7Hw==", "dev": true, "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1", + "glob": "^7.1.6", + "ignore-walk": "^3.0.3", + "npm-bundled": "^1.1.1", "npm-normalize-package-bin": "^1.0.1" } }, @@ -11068,47 +11553,19 @@ } }, "npm-registry-fetch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-4.0.7.tgz", - "integrity": "sha512-cny9v0+Mq6Tjz+e0erFAB+RYJ/AVGzkjnISiobqP8OWj9c9FLoZZu8/SPSKJWE17F1tk4018wfjV+ZbIbqC7fQ==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-9.0.0.tgz", + "integrity": "sha512-PuFYYtnQ8IyVl6ib9d3PepeehcUeHN9IO5N/iCRhyg9tStQcqGQBRVHmfmMWPDERU3KwZoHFvbJ4FPXPspvzbA==", "dev": true, "requires": { - "JSONStream": "^1.3.4", - "bluebird": "^3.5.1", - "figgy-pudding": "^3.4.1", - "lru-cache": "^5.1.1", - "make-fetch-happen": "^5.0.0", - "npm-package-arg": "^6.1.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "npm-package-arg": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", - "dev": true, - "requires": { - "hosted-git-info": "^2.7.1", - "osenv": "^0.1.5", - "semver": "^5.6.0", - "validate-npm-package-name": "^3.0.0" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - } + "@npmcli/ci-detect": "^1.0.0", + "lru-cache": "^6.0.0", + "make-fetch-happen": "^8.0.9", + "minipass": "^3.1.3", + "minipass-fetch": "^1.3.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.0.0", + "npm-package-arg": "^8.0.0" } }, "npm-run-path": { @@ -11162,12 +11619,6 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, - "object-component": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", - "dev": true - }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -11313,9 +11764,9 @@ } }, "open": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/open/-/open-7.3.0.tgz", - "integrity": "sha512-mgLwQIx2F/ye9SmbrUkurZCnkoXyXyu9EbHtJZrICjVAJfyMArdHp3KkixGdZx1ZHFPNIwl0DDM1dFFqXbTLZw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/open/-/open-7.3.1.tgz", + "integrity": "sha512-f2wt9DCBKKjlFbjzGb8MOAW8LH8F0mrs1zc7KTjAJ9PZNQbfenzWbNP1VZJvw6ICMG9r14Ah6yfwPn7T7i646A==", "dev": true, "requires": { "is-docker": "^2.0.0", @@ -11345,17 +11796,17 @@ "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=" }, "ora": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.1.0.tgz", - "integrity": "sha512-9tXIMPvjZ7hPTbk8DFq1f7Kow/HU/pQYB60JbNq+QnGwcyhWVZaQ4hM9zQDEsPxw/muLpgiHSaumUZxCAmod/w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.2.0.tgz", + "integrity": "sha512-+wG2v8TUU8EgzPHun1k/n45pXquQ9fHnbXVetl9rRgO6kjZszGGbraF3XPTIdgeA+s1lbRjSEftAnyT0w8ZMvQ==", "dev": true, "requires": { + "bl": "^4.0.3", "chalk": "^4.1.0", "cli-cursor": "^3.1.0", - "cli-spinners": "^2.4.0", + "cli-spinners": "^2.5.0", "is-interactive": "^1.0.0", "log-symbols": "^4.0.0", - "mute-stream": "0.0.8", "strip-ansi": "^6.0.0", "wcwidth": "^1.0.1" }, @@ -11515,161 +11966,52 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "pacote": { - "version": "9.5.12", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.12.tgz", - "integrity": "sha512-BUIj/4kKbwWg4RtnBncXPJd15piFSVNpTzY0rysSr3VnMowTYgkGKcaHrbReepAkjTr8lH2CVWRi58Spg2CicQ==", + "version": "11.1.14", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-11.1.14.tgz", + "integrity": "sha512-6c5OhQelaJFDfiw/Zd8MfGCvvFHurSdeGzufZMPvRFImdbNOYFciOINf3DtUNUaU3h98eCb749UyHDsgvL19+A==", "dev": true, "requires": { - "bluebird": "^3.5.3", - "cacache": "^12.0.2", - "chownr": "^1.1.2", - "figgy-pudding": "^3.5.1", - "get-stream": "^4.1.0", - "glob": "^7.1.3", + "@npmcli/git": "^2.0.1", + "@npmcli/installed-package-contents": "^1.0.5", + "@npmcli/promise-spawn": "^1.2.0", + "@npmcli/run-script": "^1.3.0", + "cacache": "^15.0.5", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", "infer-owner": "^1.0.4", - "lru-cache": "^5.1.1", - "make-fetch-happen": "^5.0.0", - "minimatch": "^3.0.4", - "minipass": "^2.3.5", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "normalize-package-data": "^2.4.0", - "npm-normalize-package-bin": "^1.0.0", - "npm-package-arg": "^6.1.0", - "npm-packlist": "^1.1.12", - "npm-pick-manifest": "^3.0.0", - "npm-registry-fetch": "^4.0.0", - "osenv": "^0.1.5", - "promise-inflight": "^1.0.1", + "minipass": "^3.1.3", + "mkdirp": "^1.0.3", + "npm-package-arg": "^8.0.1", + "npm-packlist": "^2.1.4", + "npm-pick-manifest": "^6.0.0", + "npm-registry-fetch": "^9.0.0", "promise-retry": "^1.1.1", - "protoduck": "^5.0.1", - "rimraf": "^2.6.2", - "safe-buffer": "^5.1.2", - "semver": "^5.6.0", - "ssri": "^6.0.1", - "tar": "^4.4.10", - "unique-filename": "^1.1.1", - "which": "^1.3.1" + "read-package-json-fast": "^1.1.3", + "rimraf": "^3.0.2", + "ssri": "^8.0.0", + "tar": "^6.1.0" }, "dependencies": { - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true }, - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, - "requires": { - "minipass": "^2.6.0" - } + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "npm-package-arg": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", - "dev": true, - "requires": { - "hosted-git-info": "^2.7.1", - "osenv": "^0.1.5", - "semver": "^5.6.0", - "validate-npm-package-name": "^3.0.0" - } - }, - "npm-pick-manifest": { + "rimraf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz", - "integrity": "sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw==", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { - "figgy-pudding": "^3.5.1", - "npm-package-arg": "^6.0.0", - "semver": "^5.4.1" + "glob": "^7.1.3" } - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "tar": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", - "dev": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true } } }, @@ -11778,6 +12120,12 @@ "lines-and-columns": "^1.1.6" } }, + "parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true + }, "parse5": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", @@ -11802,6 +12150,23 @@ } } }, + "parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "requires": { + "parse5": "^6.0.1" + }, + "dependencies": { + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + } + } + }, "parse5-sax-parser": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-6.0.1.tgz", @@ -11819,24 +12184,6 @@ } } }, - "parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -11948,12 +12295,30 @@ } }, "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "requires": { - "find-up": "^3.0.0" + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } } }, "pngjs": { @@ -12105,23 +12470,14 @@ } }, "postcss-import": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz", - "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.0.0.tgz", + "integrity": "sha512-gFDDzXhqr9ELmnLHgCC3TbGfA6Dm/YMb/UN8/f7Uuq4fL7VTk2vOIj6hwINEwbokEmp123bLD7a5m+E+KIetRg==", "dev": true, "requires": { - "postcss": "^7.0.1", - "postcss-value-parser": "^3.2.3", + "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } } }, "postcss-less": { @@ -12134,16 +12490,16 @@ } }, "postcss-loader": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-4.0.4.tgz", - "integrity": "sha512-pntA9zIR14drQo84yGTjQJg1m7T0DkXR4vXYHBngiRZdJtEeCrojL6lOpqUanMzG375lIJbT4Yug85zC/AJWGw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-4.2.0.tgz", + "integrity": "sha512-mqgScxHqbiz1yxbnNcPdKYo/6aVt+XExURmEbQlviFVWogDbM4AJ0A/B+ZBpYsJrTRxKw7HyRazg9x0Q9SWwLA==", "dev": true, "requires": { "cosmiconfig": "^7.0.0", "klona": "^2.0.4", "loader-utils": "^2.0.0", "schema-utils": "^3.0.0", - "semver": "^7.3.2" + "semver": "^7.3.4" }, "dependencies": { "ajv": { @@ -12319,44 +12675,38 @@ } }, "postcss-modules-extract-imports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", - "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", - "dev": true, - "requires": { - "postcss": "^7.0.5" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "dev": true }, "postcss-modules-local-by-default": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", - "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", + "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", "dev": true, "requires": { - "icss-utils": "^4.1.1", - "postcss": "^7.0.32", + "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", "postcss-value-parser": "^4.1.0" } }, "postcss-modules-scope": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", - "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", "dev": true, "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0" + "postcss-selector-parser": "^6.0.4" } }, "postcss-modules-values": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", - "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", "dev": true, "requires": { - "icss-utils": "^4.0.0", - "postcss": "^7.0.6" + "icss-utils": "^5.0.0" } }, "postcss-normalize-charset": { @@ -12668,6 +13018,12 @@ "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", "dev": true }, + "pretty-bytes": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.5.0.tgz", + "integrity": "sha512-p+T744ZyjjiaFlMUZZv6YPC5JrkNj8maRmPaQCWFJFplUAzpIUTRaTcS+7wmZtUoFXHtESJb23ISliaWyz3SHA==", + "dev": true + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -12724,21 +13080,12 @@ }, "dependencies": { "@types/node": { - "version": "13.13.32", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.32.tgz", - "integrity": "sha512-sPBvDnrwZE1uePhkCEyI/qQlgZM5kePPAhHIFDWNsOrWBFRBOk3LKJYmVCLeLZlL9Ub/FzMJb31OTWCg2F+06g==" + "version": "13.13.40", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.40.tgz", + "integrity": "sha512-eKaRo87lu1yAXrzEJl0zcJxfUMDT5/mZalFyOkT44rnQps41eS2pfWzbaulSPpQLFNy29bFqn+Y5lOTL8ATlEQ==" } } }, - "protoduck": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/protoduck/-/protoduck-5.0.1.tgz", - "integrity": "sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg==", - "dev": true, - "requires": { - "genfun": "^5.0.0" - } - }, "protractor": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/protractor/-/protractor-7.0.0.tgz", @@ -13122,6 +13469,12 @@ } } }, + "puka": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/puka/-/puka-1.0.1.tgz", + "integrity": "sha512-ssjRZxBd7BT3dte1RR3VoeT2cT/ODH8x+h0rUF1rMqB0srHYf48stSDWfiYakTp5UBZMxroZhB2+ExLDHm7W3g==", + "dev": true + }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -13243,9 +13596,9 @@ } }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==" }, "yargs": { "version": "13.3.2", @@ -13404,6 +13757,16 @@ } } }, + "read-package-json-fast": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-1.2.1.tgz", + "integrity": "sha512-OFbpwnHcv74Oa5YN5WvbOBfLw6yPmPcwvyJJw/tj9cWFBF7juQUDLDSZiOjEcgzfweWeeROOmbPpNN1qm4hcRg==", + "dev": true, + "requires": { + "json-parse-even-better-errors": "^2.3.0", + "npm-normalize-package-bin": "^1.0.1" + } + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -13470,6 +13833,18 @@ "util-deprecate": "^1.0.1" } }, + "readdir-scoped-modules": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", + "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==", + "dev": true, + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, "readdirp": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", @@ -13542,34 +13917,13 @@ "dev": true }, "regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", + "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, "regexpu-core": { @@ -13593,9 +13947,9 @@ "dev": true }, "regjsparser": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", - "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.7.tgz", + "integrity": "sha512-ib77G0uxsA2ovgiYbCVGx4Pv3PSttAx2vIwidqQzbL2U5S4Q+j00HdSAneSBuyVcMvEnTXMjiGgB+DlXozVhpQ==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -13630,12 +13984,12 @@ } }, "remark-stringify": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.0.tgz", - "integrity": "sha512-8x29DpTbVzEc6Dwb90qhxCtbZ6hmj3BxWWDpMhA+1WM4dOEGH5U5/GFe3Be5Hns5MvPSFAr1e2KSVtKZkK5nUw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.1.tgz", + "integrity": "sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==", "dev": true, "requires": { - "mdast-util-to-markdown": "^0.5.0" + "mdast-util-to-markdown": "^0.6.0" } }, "remove-trailing-separator": { @@ -13656,12 +14010,6 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true - }, "request": { "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", @@ -13703,6 +14051,12 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -13867,6 +14221,31 @@ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz", "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA=", "dev": true + }, + "css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } } } }, @@ -13877,9 +14256,9 @@ "dev": true }, "rfdc": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.4.tgz", - "integrity": "sha512-5C9HXdzK8EAqN7JDif30jqsBzavB7wLpaubisuQIGHWf2gUXSpzy6ArX/+Da8RjFpagWsCn+pIgxTMAmKw9Zug==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.2.0.tgz", + "integrity": "sha512-ijLyszTMmUrXvjSooucVQwimGUk84eRcmCuLV8Xghe3UO85mjUtRAHRyoMM6XtyqbECaXuBWx18La3523sXINA==", "dev": true }, "rgb-regex": { @@ -13913,9 +14292,9 @@ } }, "rollup": { - "version": "2.32.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.32.1.tgz", - "integrity": "sha512-Op2vWTpvK7t6/Qnm1TTh7VjEZZkN8RWgf0DHbkKzQBwNf748YhXbozHVefqpPp/Fuyk/PQPAnYsBxAEtlMvpUw==", + "version": "2.36.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.36.1.tgz", + "integrity": "sha512-eAfqho8dyzuVvrGqpR0ITgEdq0zG2QJeWYh+HeuTbpcaXk8vNFc48B7bJa1xYosTCKx0CuW+447oQOW8HgBIZQ==", "dev": true, "requires": { "fsevents": "~2.1.2" @@ -13977,18 +14356,18 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sass": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.27.0.tgz", - "integrity": "sha512-0gcrER56OkzotK/GGwgg4fPrKuiFlPNitO7eUJ18Bs+/NBlofJfMxmxqpqJxjae9vu0Wq8TZzrSyxZal00WDig==", + "version": "1.32.4", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.4.tgz", + "integrity": "sha512-N0BT0PI/t3+gD8jKa83zJJUb7ssfQnRRfqN+GIErokW6U4guBpfYl8qYB+OFLEho+QvnV5ZH1R9qhUC/Z2Ch9w==", "dev": true, "requires": { "chokidar": ">=2.0.0 <4.0.0" } }, "sass-loader": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.0.5.tgz", - "integrity": "sha512-2LqoNPtKkZq/XbXNQ4C64GFEleSEHKv6NPSI+bMC/l+jpEXGJhiRYkAQToO24MR7NU4JRY2RpLpJ/gjo2Uf13w==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.1.1.tgz", + "integrity": "sha512-W6gVDXAd5hR/WHsPicvZdjAWHBcEJ44UahgxcIE196fW2ong0ZHMPO1kZuI5q0VlvMQZh32gpv69PLWQm70qrw==", "dev": true, "requires": { "klona": "^2.0.4", @@ -14466,6 +14845,19 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } } } }, @@ -14541,152 +14933,70 @@ } }, "socket.io": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz", - "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.0.tgz", + "integrity": "sha512-Aqg2dlRh6xSJvRYK31ksG65q4kmBOqU4g+1ukhPcoT6wNGYoIwSYPlCPuRwOO9pgLUajojGFztl6+V2opmKcww==", "dev": true, "requires": { - "debug": "~4.1.0", - "engine.io": "~3.4.0", - "has-binary2": "~1.0.2", - "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.3.0", - "socket.io-parser": "~3.4.0" + "@types/cookie": "^0.4.0", + "@types/cors": "^2.8.8", + "@types/node": "^14.14.10", + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.1", + "engine.io": "~4.1.0", + "socket.io-adapter": "~2.1.0", + "socket.io-parser": "~4.0.3" }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } } } }, "socket.io-adapter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", - "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz", + "integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg==", "dev": true }, - "socket.io-client": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz", - "integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==", - "dev": true, - "requires": { - "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "~4.1.0", - "engine.io-client": "~3.4.0", - "has-binary2": "~1.0.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "socket.io-parser": "~3.3.0", - "to-array": "0.1.4" - }, - "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true - }, - "socket.io-parser": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", - "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "isarray": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - } - } - }, "socket.io-parser": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz", - "integrity": "sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz", + "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", "dev": true, "requires": { - "component-emitter": "1.2.1", - "debug": "~4.1.0", - "isarray": "2.0.1" + "@types/component-emitter": "^1.2.10", + "component-emitter": "~1.3.0", + "debug": "~4.3.1" }, "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } - }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true } } }, "sockjs": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", - "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==", + "version": "0.3.21", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz", + "integrity": "sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==", "dev": true, "requires": { - "faye-websocket": "^0.10.0", + "faye-websocket": "^0.11.3", "uuid": "^3.4.0", - "websocket-driver": "0.6.5" + "websocket-driver": "^0.7.4" }, "dependencies": { "uuid": { @@ -14698,57 +15008,56 @@ } }, "sockjs-client": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", - "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.0.tgz", + "integrity": "sha512-8Dt3BDi4FYNrCFGTL/HtwVzkARrENdwOUf1ZoW/9p3M8lZdFT35jVdrHza+qgxuG9H3/shR4cuX/X9umUrjP8Q==", "dev": true, "requires": { - "debug": "^3.2.5", + "debug": "^3.2.6", "eventsource": "^1.0.7", - "faye-websocket": "~0.11.1", - "inherits": "^2.0.3", - "json3": "^3.3.2", - "url-parse": "^1.4.3" - }, - "dependencies": { - "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - } + "faye-websocket": "^0.11.3", + "inherits": "^2.0.4", + "json3": "^3.3.3", + "url-parse": "^1.4.7" } }, "socks": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.3.3.tgz", - "integrity": "sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.5.1.tgz", + "integrity": "sha512-oZCsJJxapULAYJaEYBSzMcz8m3jqgGrHaGhkmU/o/PQfFWYWxkAaA0UMGImb6s6tEXfKi959X6VJjMMQ3P6TTQ==", "dev": true, "requires": { - "ip": "1.1.5", + "ip": "^1.1.5", "smart-buffer": "^4.1.0" } }, "socks-proxy-agent": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz", - "integrity": "sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz", + "integrity": "sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA==", "dev": true, "requires": { - "agent-base": "~4.2.1", - "socks": "~2.3.2" + "agent-base": "6", + "debug": "4", + "socks": "^2.3.3" }, "dependencies": { "agent-base": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "requires": { - "es6-promisify": "^5.0.0" + "debug": "4" + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" } } } @@ -14766,9 +15075,9 @@ "dev": true }, "source-map-loader": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-1.1.2.tgz", - "integrity": "sha512-bjf6eSENOYBX4JZDfl9vVLNsGAQ6Uz90fLmOazcmMcyDYOBFsGxPNn83jXezWLY9bJsVAo1ObztxPcV8HAbjVA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-1.1.3.tgz", + "integrity": "sha512-6YHeF+XzDOrT/ycFJNI53cgEsp/tHTMl37hi7uVyqFAlTXW109JazaQCkbc+jjoL2637qkH1amLi+JzrIpt5lA==", "dev": true, "requires": { "abab": "^2.0.5", @@ -14814,16 +15123,13 @@ } }, "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", + "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", "dev": true, "requires": { "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" + "decode-uri-component": "^0.2.0" } }, "source-map-support": { @@ -15139,9 +15445,9 @@ "dev": true }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -15293,9 +15599,9 @@ } }, "stylelint": { - "version": "13.8.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.8.0.tgz", - "integrity": "sha512-iHH3dv3UI23SLDrH4zMQDjLT9/dDIz/IpoFeuNxZmEx86KtfpjDOscxLTFioQyv+2vQjPlRZnK0UoJtfxLICXQ==", + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.9.0.tgz", + "integrity": "sha512-VVWH2oixOAxpWL1vH+V42ReCzBjW2AeqskSAbi8+3OjV1Xg3VZkmTcAqBZfRRvJeF4BvYuDLXebW3tIHxgZDEg==", "dev": true, "requires": { "@stylelint/postcss-css-in-js": "^0.37.2", @@ -15304,14 +15610,14 @@ "balanced-match": "^1.0.0", "chalk": "^4.1.0", "cosmiconfig": "^7.0.0", - "debug": "^4.2.0", + "debug": "^4.3.1", "execall": "^2.0.0", - "fast-glob": "^3.2.4", + "fast-glob": "^3.2.5", "fastest-levenshtein": "^1.0.12", "file-entry-cache": "^6.0.0", "get-stdin": "^8.0.0", "global-modules": "^2.0.0", - "globby": "^11.0.1", + "globby": "^11.0.2", "globjoin": "^0.1.4", "html-tags": "^3.1.0", "ignore": "^5.1.8", @@ -15321,7 +15627,7 @@ "lodash": "^4.17.20", "log-symbols": "^4.0.0", "mathml-tag-names": "^2.1.3", - "meow": "^8.0.0", + "meow": "^9.0.0", "micromatch": "^4.0.2", "normalize-selector": "^0.2.0", "postcss": "^7.0.35", @@ -15343,7 +15649,7 @@ "style-search": "^0.1.0", "sugarss": "^2.0.0", "svg-tags": "^1.0.0", - "table": "^6.0.3", + "table": "^6.0.7", "v8-compile-cache": "^2.2.0", "write-file-atomic": "^3.0.3" }, @@ -15363,6 +15669,12 @@ "color-convert": "^2.0.1" } }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -15397,6 +15709,34 @@ "ms": "2.1.2" } }, + "fast-glob": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, + "globby": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz", + "integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -15489,18 +15829,6 @@ } } }, - "postcss-selector-parser": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz", - "integrity": "sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1", - "util-deprecate": "^1.0.2" - } - }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", @@ -15631,9 +15959,9 @@ } }, "stylus-loader": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-4.3.1.tgz", - "integrity": "sha512-apDYJEM5ZpOAWbWInWcsbtI8gHNr/XYVcSY/tWqOUPt7M5tqhtwXVsAkgyiVjhuvw2Yrjq474a9H+g4d047Ebw==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-4.3.2.tgz", + "integrity": "sha512-xXVKHY+J7GBlOmqjCL1VvQfc+pFkBdWGtcpJSvBGE49nWWHaukox7KCjRdLTEzjrmHODm4+rLpqkYWzfJteMXQ==", "dev": true, "requires": { "fast-glob": "^3.2.4", @@ -15714,32 +16042,32 @@ } }, "symbol-observable": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-2.0.3.tgz", - "integrity": "sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-3.0.0.tgz", + "integrity": "sha512-6tDOXSHiVjuCaasQSWTmHUWn4PuG7qa3+1WT031yTc/swT7+rLiw3GOrFxaH1E3lLP09dH3bVuVDf2gK5rxG3Q==", "dev": true }, "table": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/table/-/table-6.0.4.tgz", - "integrity": "sha512-sBT4xRLdALd+NFBvwOz8bw4b15htyythha+q+DVZqy2RS08PPC8O2sZFgJYEY7bJvbCFKccs+WIZ/cd+xxTWCw==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz", + "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==", "dev": true, "requires": { - "ajv": "^6.12.4", + "ajv": "^7.0.2", "lodash": "^4.17.20", "slice-ansi": "^4.0.0", "string-width": "^4.2.0" }, "dependencies": { "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.3.tgz", + "integrity": "sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, @@ -15755,6 +16083,12 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "lodash": { "version": "4.17.20", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", @@ -15790,9 +16124,9 @@ "dev": true }, "tar": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz", - "integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", "dev": true, "requires": { "chownr": "^2.0.0", @@ -15818,9 +16152,9 @@ } }, "terser": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.3.7.tgz", - "integrity": "sha512-lJbKdfxWvjpV330U4PBZStCT9h3N9A4zZVA5Y4k9sCWXknrpdyxi1oMsRKLmQ/YDMDxSBKIh88v0SkdhdqX06w==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.5.1.tgz", + "integrity": "sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ==", "dev": true, "requires": { "commander": "^2.20.0", @@ -15981,12 +16315,6 @@ "os-tmpdir": "~1.0.2" } }, - "to-array": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", - "dev": true - }, "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", @@ -16111,9 +16439,9 @@ "dev": true }, "ts-protoc-gen": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/ts-protoc-gen/-/ts-protoc-gen-0.13.0.tgz", - "integrity": "sha512-j18X4rkDBbG/ZHUJy88WFeZP6mStGow5uREaohowlHXTu3/N7WcpyPhb7Vh6wN38ERmc/AkT9gqT98+vtlRhJA==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/ts-protoc-gen/-/ts-protoc-gen-0.14.0.tgz", + "integrity": "sha512-2z6w2HioMCMVNcgNHBcEvudmQfzrn+3BjAlz+xgYZ9L0o8n8UG8WUiTJcbXHFiEg2SU8IltwH2pm1otLoMSKwg==", "requires": { "google-protobuf": "^3.6.1" } @@ -16234,9 +16562,9 @@ "dev": true }, "ua-parser-js": { - "version": "0.7.22", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.22.tgz", - "integrity": "sha512-YUxzMjJ5T71w6a8WWVcMGM6YWOTX27rCoIQgLXiWaxqXSx9D7DNjiGWn1aJIRSQ5qr0xuhra77bSIh6voR/46Q==", + "version": "0.7.23", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.23.tgz", + "integrity": "sha512-m4hvMLxgGHXG3O3fQVAyyAQpZzDOvwnhOTjYz5Xmr7r/+LpkNy3vJXdVRWgd1TkAb7NGROZuSy96CrlNVjA7KA==", "dev": true }, "unicode-canonical-property-names-ecmascript": { @@ -16341,9 +16669,9 @@ } }, "unist-util-is": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.3.tgz", - "integrity": "sha512-bTofCFVx0iQM8Jqb1TBDVRIQW03YkD3p66JOd/aCWuqzlLyUtx1ZAGw/u+Zw+SttKvSVcvTiKYbfrtLoLefykw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.4.tgz", + "integrity": "sha512-3dF39j/u423v4BBQrk1AQ2Ve1FxY5W3JKwXxVFzBODQ6WEvccguhgp802qQLKSnxPODE6WuRZtV+ohlUg4meBA==", "dev": true }, "unist-util-stringify-position": { @@ -16648,14 +16976,13 @@ } }, "vfile": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.0.tgz", - "integrity": "sha512-a/alcwCvtuc8OX92rqqo7PflxiCgXRFjdyoGVuYV+qbgCb0GgZJRvIgCD4+U/Kl1yhaRsaTwksF88xbPyGsgpw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", "dev": true, "requires": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", - "replace-ext": "1.0.0", "unist-util-stringify-position": "^2.0.0", "vfile-message": "^2.0.0" }, @@ -17060,9 +17387,9 @@ } }, "enhanced-resolve": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz", - "integrity": "sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", + "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -17151,6 +17478,16 @@ "yallist": "^3.0.2" } }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -17172,6 +17509,15 @@ "to-regex": "^3.0.2" } }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -17313,17 +17659,17 @@ }, "dependencies": { "mime": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", - "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.0.tgz", + "integrity": "sha512-ft3WayFSFUVBuJj7BMLKAQcSlItKtfjsKDDsii3rqFDAZ7t11zRe8ASw/GlmivGwVUYtwkQrxiGGpL6gFvB0ag==", "dev": true } } }, "webpack-dev-server": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz", - "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==", + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz", + "integrity": "sha512-u4R3mRzZkbxQVa+MBWi2uVpB5W59H3ekZAJsQlKUTdl7Elcah2EhygTPLmeFXybQkf9i2+L0kn7ik9SnXa6ihQ==", "dev": true, "requires": { "ansi-html": "0.0.7", @@ -17346,11 +17692,11 @@ "p-retry": "^3.0.1", "portfinder": "^1.0.26", "schema-utils": "^1.0.0", - "selfsigned": "^1.10.7", + "selfsigned": "^1.10.8", "semver": "^6.3.0", "serve-index": "^1.9.1", - "sockjs": "0.3.20", - "sockjs-client": "1.4.0", + "sockjs": "^0.3.21", + "sockjs-client": "^1.5.0", "spdy": "^4.0.2", "strip-ansi": "^3.0.1", "supports-color": "^6.1.0", @@ -17749,9 +18095,9 @@ } }, "webpack-merge": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.2.0.tgz", - "integrity": "sha512-QBglJBg5+lItm3/Lopv8KDDK01+hjdg2azEwi/4vKJ8ZmGPdtJsTpjtNNOW3a4WiqzXdCATtTudOZJngE7RKkA==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", + "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", "dev": true, "requires": { "clone-deep": "^4.0.1", @@ -17759,9 +18105,9 @@ } }, "webpack-sources": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.0.1.tgz", - "integrity": "sha512-A9oYz7ANQBK5EN19rUXbvNgfdfZf5U2gP0769OXsj9CvYkCR6OHOsd6OKyEy4H38GGxpsQPKIL83NC64QY6Xmw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", + "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", "dev": true, "requires": { "source-list-map": "^2.0.1", @@ -17769,9 +18115,9 @@ } }, "webpack-subresource-integrity": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.5.1.tgz", - "integrity": "sha512-uekbQ93PZ9e7BFB8Hl9cFIVYQyQqiXp2ExKk9Zv+qZfH/zHXHrCFAfw1VW0+NqWbTWrs/HnuDrto3+tiPXh//Q==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.5.2.tgz", + "integrity": "sha512-GBWYBoyalbo5YClwWop9qe6Zclp8CIXYGIz12OPclJhIrSplDxs1Ls1JDMH8xBPPrg1T6ISaTW9Y6zOrwEiAzw==", "dev": true, "requires": { "webpack-sources": "^1.3.0" @@ -17790,11 +18136,13 @@ } }, "websocket-driver": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", - "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "dev": true, "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, @@ -17934,12 +18282,6 @@ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", "dev": true }, - "xmlhttprequest-ssl": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", - "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", - "dev": true - }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -17993,12 +18335,6 @@ } } }, - "yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", - "dev": true - }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/console/package.json b/console/package.json index a53f385b39..042903a453 100644 --- a/console/package.json +++ b/console/package.json @@ -28,40 +28,40 @@ "@types/google-protobuf": "^3.7.4", "@types/uuid": "^8.3.0", "angular-oauth2-oidc": "^10.0.3", - "angularx-qrcode": "^10.0.11", + "angularx-qrcode": "^11.0.0", "cors": "^2.8.5", "file-saver": "^2.0.5", - "google-proto-files": "^2.3.0", + "google-proto-files": "^2.4.0", "google-protobuf": "^3.13.0", "grpc": "^1.24.3", "grpc-web": "^1.2.1", "moment": "^2.29.1", "ngx-quicklink": "^0.2.6", "rxjs": "~6.6.3", - "ts-protoc-gen": "^0.13.0", + "ts-protoc-gen": "^0.14.0", "tslib": "^2.0.0", "uuid": "^8.3.2", "zone.js": "~0.11.3" }, "devDependencies": { - "@angular-devkit/build-angular": "~0.1100.4", - "@angular/cli": "~11.0.4", + "@angular/cli": "~11.1.2", + "@angular-devkit/build-angular": "~0.1101.2", "@angular/compiler-cli": "~11.0.0", - "@types/jasmine": "~3.6.2", - "@angular/language-service": "~11.0.4", + "@types/jasmine": "~3.6.3", + "@angular/language-service": "~11.1.1", "@types/jasminewd2": "~2.0.3", - "@types/node": "^14.14.13", + "@types/node": "^14.14.22", "codelyzer": "^6.0.0", "jasmine-core": "~3.6.0", "jasmine-spec-reporter": "~6.0.0", - "karma": "~5.2.3", + "karma": "~6.0.3", "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.8.0", + "stylelint": "^13.9.0", "stylelint-config-standard": "^20.0.0", "stylelint-scss": "^3.18.0", "ts-node": "~9.1.1", diff --git a/console/src/app/favicon-96x96.ico b/console/src/app/favicon-96x96.ico new file mode 100644 index 0000000000000000000000000000000000000000..0b13cbabf6c535ee6f055df18ec7470eedbebc3e GIT binary patch literal 38078 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 implements UnaryInterceptor { + public triggerDialog: Subject = new Subject(); constructor( private authenticationService: AuthenticationService, private storageService: StorageService, private dialog: MatDialog, - ) { } + ) { + this.triggerDialog.pipe(debounceTime(1000)).subscribe(() => { + this.openDialog(); + }); + } public async intercept(request: Request, invoker: any): Promise> { await this.authenticationService.authenticationChanged.pipe( @@ -36,22 +42,26 @@ export class AuthInterceptor implements UnaryIn return response; }).catch((error: any) => { if (error.code === 16) { - const dialogRef = this.dialog.open(WarnDialogComponent, { - data: { - confirmKey: 'ACTIONS.LOGIN', - titleKey: 'ERRORS.TOKENINVALID.TITLE', - descriptionKey: 'ERRORS.TOKENINVALID.DESCRIPTION', - }, - width: '400px', - }); - - dialogRef.afterClosed().pipe(take(1)).subscribe(resp => { - if (resp) { - this.authenticationService.authenticate(undefined, true, true); - } - }); + this.triggerDialog.next(true); } return Promise.reject(error); }); } + + openDialog() { + const dialogRef = this.dialog.open(WarnDialogComponent, { + data: { + confirmKey: 'ACTIONS.LOGIN', + titleKey: 'ERRORS.TOKENINVALID.TITLE', + descriptionKey: 'ERRORS.TOKENINVALID.DESCRIPTION', + }, + width: '400px', + }); + + dialogRef.afterClosed().pipe(take(1)).subscribe(resp => { + if (resp) { + this.authenticationService.authenticate(undefined, true, true); + } + }); + } } diff --git a/console/src/assets/icons/android-chrome-512x512.png b/console/src/assets/icons/android-chrome-512x512.png index 0112bc8bceb70156e586e0288db06bbf68f2ecad..6987ed11b45db3179879b2e0892a7afcdd891249 100644 GIT binary patch literal 137768 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%0Alqi6e`R9*-RHY{A1J_h!rpC3ru6ZTA) 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 diff --git a/go.mod b/go.mod index 5e829050b7..f1a3c5e377 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.15 require ( cloud.google.com/go v0.71.0 // indirect + cloud.google.com/go/storage v1.10.0 github.com/BurntSushi/toml v0.3.1 github.com/DATA-DOG/go-sqlmock v1.5.0 github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v0.13.0 @@ -16,9 +17,10 @@ require ( 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/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 - github.com/envoyproxy/protoc-gen-validate v0.4.1 + github.com/envoyproxy/protoc-gen-validate v0.1.0 github.com/ghodss/yaml v1.0.0 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/golang/mock v1.4.4 @@ -41,16 +43,19 @@ require ( github.com/kevinburke/twilio-go v0.0.0-20200810163702-320748330fac github.com/kr/text v0.2.0 // indirect github.com/lib/pq v1.9.0 - github.com/mattn/go-colorable v0.1.8 // indirect + github.com/manifoldco/promptui v0.7.0 + github.com/mattn/go-colorable v0.1.8 // indirect; indirect github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mitchellh/reflectwalk v1.0.1 // indirect github.com/nicksnyder/go-i18n/v2 v2.1.1 + github.com/pkg/errors v0.9.1 github.com/pquerna/otp v1.2.0 github.com/prometheus/client_golang v1.8.0 // indirect github.com/prometheus/common v0.15.0 // indirect github.com/rakyll/statik v0.1.7 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/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 // indirect github.com/ttacon/libphonenumber v1.1.0 @@ -66,10 +71,15 @@ require ( golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect golang.org/x/text v0.3.4 golang.org/x/tools v0.0.0-20201103235415-b653051172e4 + google.golang.org/api v0.34.0 google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20201103154000-415bd0cd5df6 google.golang.org/grpc v1.34.0 google.golang.org/protobuf v1.25.0 gopkg.in/square/go-jose.v2 v2.5.1 - gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect + gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c + gotest.tools v2.2.0+incompatible + k8s.io/api v0.18.5 + k8s.io/apiextensions-apiserver v0.18.5 + k8s.io/apimachinery v0.18.5 ) diff --git a/go.sum b/go.sum index cfe27d1e96..7e54c9f28f 100644 --- a/go.sum +++ b/go.sum @@ -44,6 +44,18 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/AlecAivazis/survey/v2 v2.0.8 h1:zVjWKN+JIAfmrq6nGWG3DfLS8ypEBhxYy0p7FM+riFk= +github.com/AlecAivazis/survey/v2 v2.0.8/go.mod h1:9FJRdMdDm8rnT+zHVbvQT2RTSTLq0Ttd6q3Vl2fahjk= +github.com/AppsFlyer/go-sundheit v0.2.0 h1:FArqX+HbqZ6U32RC3giEAWRUpkggqxHj91KIvxNgwjU= +github.com/AppsFlyer/go-sundheit v0.2.0/go.mod h1:rCRkVTMQo7/krF7xQ9X0XEF1an68viFR6/Gy02q+4ds= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -58,22 +70,34 @@ github.com/DataDog/sketches-go v0.0.1/go.mod h1:Q5DbzQ+3AkgGwymQO7aZFNP7ns2lZKGt github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v0.13.0 h1:fjKUtfldCPIF4nIzAAj3LzP8Lrd3DuRIMiFdOsj4fLc= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v0.13.0/go.mod h1:q/paYxLXKVhwfC3lzLfhtL54fAx14wzMN9DundQOBMc= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/PuerkitoBio/goquery v1.5.1 h1:PSPBGne8NIUWw+/7vFBV+kG2J/5MOjbzc7154OaKCSE= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw= +github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VictoriaMetrics/fastcache v1.5.7 h1:4y6y0G8PRzszQUYIQHHssv/jgPHAb5qQuuDNdCbyAgw= github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/ajstarks/svgo v0.0.0-20200725142600-7a3c8b57fecb h1:EVl3FJLQCzSbgBezKo/1A4ADnJ4mtJZ0RvnNzDJ44nY= github.com/ajstarks/svgo v0.0.0-20200725142600-7a3c8b57fecb/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= +github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -82,146 +106,211 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5 github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo= +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/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= +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= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +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/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= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= 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= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= +github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/caos/logging v0.0.2 h1:ebg5C/HN0ludYR+WkvnFjwSExF4wvyiWPyWGcKMYsoo= +github.com/caos/logging v0.0.0-20191210002624-b3260f690a6a/go.mod h1:9LKiDE2ChuGv6CHYif/kiugrfEXu9AwDiFWSreX7Wp0= 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/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/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= +github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= 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/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= +github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= 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 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cfssl v0.0.0-20190726000631-633726f6bcb7 h1:Puu1hUwfps3+1CUzYdAZXijuvLuRMirgiXdf3zsM2Ig= github.com/cloudflare/cfssl v0.0.0-20190726000631-633726f6bcb7/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU= +github.com/cloudflare/cloudflare-go v0.12.1/go.mod h1:gmzHQPAyHh8N8UgX0Z+3rSMRbNj47JDEbzXDICHVXys= +github.com/cloudscale-ch/cloudscale-go-sdk v1.6.0/go.mod h1:FhOTOCgKAVvRRMQc1mC0D7xK/3zYnmcZBWFXNkacvMc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/cockroach-go/v2 v2.1.0 h1:zicZlBhWZu6wfK7Ezg4Owdc3HamLpRdBllPTT9tb+2k= github.com/cockroachdb/cockroach-go/v2 v2.1.0/go.mod h1:ilhrLnPDDwGHL+iK2UxQhp1UzUhst8sfItSAgCYwAyg= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +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/creack/pty v1.1.7 h1:6pwm8kMQKCmgUg0ZHTm5+/YvRK0s3THD/28+T6/kk4A= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= 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/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ= +github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= 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= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/duo-labs/webauthn v0.0.0-20200714211715-1daaee874e43 h1:eEEfwrmEwl0LVuWz/VkAefdgtPbX174Huu5dxxceihI= github.com/duo-labs/webauthn v0.0.0-20200714211715-1daaee874e43/go.mod h1:/X2OJiJxjQ7alqWZqX9EtBTmZc+4qQ0LvZ1k5wP67RM= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= 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/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= +github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4 h1:rEvIZUSZ3fx39WIi3JkQqQBitGwpELBIYWeBVh6wn+E= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= 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/envoyproxy/protoc-gen-validate v0.4.1 h1:7dLaJvASGRD7X49jSCSXXHwKPm0ZN9r9kJD+p+vS7dM= -github.com/envoyproxy/protoc-gen-validate v0.4.1/go.mod h1:E+IEazqdaWv3FrnGtZIu3b9fPFMK8AzeTTrk9SfVwWs= -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/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/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/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/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= +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= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= +github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= +github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= +github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk= +github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= +github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= +github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= +github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= +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-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= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= 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= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= @@ -231,10 +320,10 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -245,49 +334,38 @@ github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw= github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho= +github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8= +github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/certificate-transparency-go v1.0.21 h1:Yf1aXowfZ2nuboBsg7iYGLmwsOARdV86pfH3g95wXmE= github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-github/v31 v31.0.0 h1:JJUxlP9lFK+ziXKimTCprajMApV1ecWD4NB6CCb0plo= github.com/google/go-github/v31 v31.0.0/go.mod h1:NQPZol8/1sMoWYGN2yaALIBytu17gAWfhbweiEed3pM= -github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= 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 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 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= @@ -296,41 +374,48 @@ github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99 h1:Ak8CrdlwwXwAZxzS66vgPt4U8yUZX7JwLvVR58FN5jM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +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/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -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= -github.com/googleinterns/cloud-operations-api-mock v0.0.0-20200709193332-a1e58c29bdd3 h1:eHv/jVY/JNop1xg2J9cBb4EzyMpWZoNCP1BslSAIkOI= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +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/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= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/csrf v1.7.0 h1:mMPjV5/3Zd460xCavIkppUdvnl5fPXMpv2uz2Zyg7/Y= github.com/gorilla/csrf v1.7.0/go.mod h1:+a/4tCmqhG6/w4oafeAZ9pEa3/NZOWYVbD9fV0FwIQA= +github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU= github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc= github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU= github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 h1:FlFbCRLd5Jr4iYXZufAvgWN6Ao0JrI5chLINnUXDDr0= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= @@ -349,59 +434,48 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= 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/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A= 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= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/iancoleman/strcase v0.0.0-20180726023541-3605ed457bf7 h1:ux/56T2xqZO/3cP1I2F86qpeoYPCOzk+KF/UH/Ar+lk= -github.com/iancoleman/strcase v0.0.0-20180726023541-3605ed457bf7/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= 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/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 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= -github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk= -github.com/jackc/pgconn v1.5.0 h1:oFSOilzIZkyg787M1fEmyMfOUUvwj0daqYMfaWwNL4o= github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= github.com/jackc/pgconn v1.7.0/go.mod h1:sF/lPpNEMEOp+IYhyQGdAvrG20gWf6A1tKlr0v7JMeA= github.com/jackc/pgconn v1.7.2/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= -github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= -github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2 h1:JVX6jT/XfzNqIjye4717ITLaNwV9mWbJx0dLCpcRzdA= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= -github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A= github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= -github.com/jackc/pgproto3/v2 v2.0.1 h1:Rdjp4NFjwHnEslx2b66FfCI2S0LhO4itac3hXz6WX9M= github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.0.5/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8 h1:Q3tB+ExeflWUW7AFcAhXqk40s9mnNYLk1nOkKNZ5GnU= github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= @@ -422,61 +496,63 @@ github.com/jackc/pgx/v4 v4.9.0/go.mod h1:MNGWmViCgqbZck9ujOOBN63gK9XVGILXWCvKLGK github.com/jackc/pgx/v4 v4.9.2/go.mod h1:Jt/xJDqjUDUOMSv8VMWPQlCObVgF2XOgqKsW8S4ROYA= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.0 h1:musOWczZC/rSbqut475Vfcczg7jJsdUQf0D6oKPLgNU= github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.2/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= 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 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M= 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/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA= +github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +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/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kataras/tablewriter v0.0.0-20180708051242-e063d29b7c23/go.mod h1:kBSna6b0/RzsOcOZf515vAXwSsXYusl2U7SA0XP09yI= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/go-types v0.0.0-20200309064045-f2d4aea18a7a h1:Z7+SSApKiwPjNic+NF9+j7h657Uyvdp/jA3iTKhpj4E= github.com/kevinburke/go-types v0.0.0-20200309064045-f2d4aea18a7a/go.mod h1:/Pk5i/SqYdYv1cie5wGwoZ4P6TpgMi+Yf58mtJSHdOw= github.com/kevinburke/go.uuid v1.2.0 h1:+1qP8NdkJfgOSTrrrUuA7h0djr1VY77HFXYjR+zUcUo= github.com/kevinburke/go.uuid v1.2.0/go.mod h1:9gVngk1Hq1FjwewVAjsWEUT+xc6jP+p62CASaGmQ0NQ= github.com/kevinburke/rest v0.0.0-20200429221318-0d2892b400f8 h1:KpuDJTaTPQAyWqETt70dHX3pMz65/XYTAZymrKKNvh8= github.com/kevinburke/rest v0.0.0-20200429221318-0d2892b400f8/go.mod h1:pD+iEcdAGVXld5foVN4e24zb/6fnb60tgZPZ3P/3T/I= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kevinburke/twilio-go v0.0.0-20200810163702-320748330fac h1:qQ7NAZEHpTyDfmZBH79KEiH3OK47Z+KvYVSR4sS3650= github.com/kevinburke/twilio-go v0.0.0-20200810163702-320748330fac/go.mod h1:Fm9alkN1/LPVY1eqD/psyMwPWE4VWl4P01/nTYZKzBk= -github.com/kisielk/errcheck v1.1.0 h1:ZqfnKyx9KGpRcW04j5nnPDgRgoXUeLh2YFBeFzphcA0= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= -github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI= +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/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/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= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -485,13 +561,24 @@ github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.4.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8= github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lyft/protoc-gen-star v0.5.1/go.mod h1:9toiA3cC7z5uVbODF7kEQ91Xn7XNFkVUl+SrEe+ZORU= +github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= +github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/manifoldco/promptui v0.7.0/go.mod h1:n4zTdgP0vr0S3w7/O/g98U+e0gwLScEXGwov2nIKuGQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -501,36 +588,45 @@ github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +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= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE= github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= @@ -540,19 +636,24 @@ 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= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= +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/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/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= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= @@ -561,79 +662,87 @@ github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pires/go-proxyproto v0.3.0 h1:++BY4zWOpWha50IDjdnp7+NRTLuOHqMQC5PkgS7I4u4= +github.com/pires/go-proxyproto v0.3.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok= github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.8.0 h1:zvJNkoCFAnYFNC24FV8nW4JdRJ3GIFcLbg65lL/JDcw= github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.15.0 h1:4fgOnadei3EZvgRwxJ7RMpG1k1pOZth5Pc13tyspaKM= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= -github.com/rs/zerolog v1.15.0 h1:uPRuwkWF4J6fGsJ2R0Gn2jB1EQiav9k3S6CSdygQJXY= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/shopspring/decimal v0.0.0-20200419222939-1884f454f8ea h1:jaXWVFZ98/ihXniiDzqNXQgMSgklX4kjfDWZTE3ZtdU= github.com/shopspring/decimal v0.0.0-20200419222939-1884f454f8ea/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= @@ -644,55 +753,75 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sony/sonyflake v1.0.0 h1:MpU6Ro7tfXwgn2l5eluf9xQvQJDROTBImNCfRXn/YeM= github.com/sony/sonyflake v1.0.0/go.mod h1:Jv3cfhf/UFtolOTTRd3q4Nl6ENqM+KfyZ5PseKfZGF4= -github.com/spf13/afero v1.3.3 h1:p5gZEKLYoL7wh8VrJesMaYeNxdEd1v3cb4irOk9zB54= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.3.4 h1:8q6vk3hthlpb2SouZcnBVKboxWQWMDNF38bwholZrJc= -github.com/spf13/afero v1.3.4/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= +github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= 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/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= github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 h1:5u+EJUQiosu3JFX0XS0qTf5FznsMOzTjGqavBGuCbo0= github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2/go.mod h1:4kyMkleCiLkgY6z8gK5BkI01ChBtxR0ro3I1ZDcGM3w= github.com/ttacon/libphonenumber v1.1.0 h1:tC6kE4t8UI4OqQVQjW5q8gSWhG2wnY5moEpSEORdYm4= github.com/ttacon/libphonenumber v1.1.0/go.mod h1:E0TpmdVMq5dyVlQ7oenAkhsLu86OkUl+yR4OAxyEg/M= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= +github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32 h1:5tjfNdR2ki3yYQ842+eX2sQHeiwpKJ0RnHO4IYOc4V8= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/zenazn/goji v0.9.0 h1:RSQQAbXGArQ0dIDEq+PI6WqN6if+5KHu6x2Cx/GXLTQ= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= @@ -713,36 +842,38 @@ go.opentelemetry.io/otel/exporters/stdout v0.13.0/go.mod h1:JJt8RpNY6K+ft9ir3iKp go.opentelemetry.io/otel/sdk v0.13.0 h1:4VCfpKamZ8GtnepXxMRurSpHpMKkcxhtO33z1S4rGDQ= go.opentelemetry.io/otel/sdk v0.13.0/go.mod h1:dKvLH8Uu8LcEPlSAUsfW7kMGaJBhk/1NYvpPZ6wIMbU= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191128160524-b544559bb6d1/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -755,11 +886,9 @@ golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -769,25 +898,22 @@ golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 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 h1:0IiAsCRByjO2QjX7ZPkw5oU9x+n1YqRL802rjC0c3Aw= 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 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -796,38 +922,37 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f h1:QBjCr1Fz5kw158VqdE9JfI9cJnl/ymnJWAdMuinqL7Y= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA= golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201026091529-146b70c837a4/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -835,9 +960,10 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 h1:42cLlJJdEh+ySyeUUbEQ5bsTi golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190517181255-950ef44c6e07/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191122200657-5d9234df094c/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 h1:ld7aEMNHoBnnDAX15v1T6z31v8HwR2A9FYOuAhWqkwc= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= @@ -846,14 +972,12 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -862,24 +986,29 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191206220618-eeba5f6aabab h1:FvshnhkKW+LO3HWHodML8kuVX8rnJTxKm9dFPuI68UM= golang.org/x/sys v0.0.0-20191206220618-eeba5f6aabab/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -891,44 +1020,42 @@ golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ixkcwXThoiF6yf+R9scA= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121 h1:rITEj+UZHYC927n8GT97eC3zrpzXdb/voyeOuVKS46o= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642 h1:B6caxRw+hozq68X2MY7jEpZh/cr4/aHLv9xU8Kkadrw= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= 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/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= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s= +golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -937,14 +1064,17 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 h1:5Beo0mZN8dRzgrMMkDp0jc8YXQKx9DiJ2k1dkvGsn5A= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -961,36 +1091,29 @@ golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56 h1:DFtSed2q3HtNuVazwVDZ4nSRS/JrZEig0gz2BY4VNrg= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4 h1:kDtqNkeBrZb8B+atrj50B5XLHpzXXqcCdZPP/ApQ5NY= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200701151220-7cb253f4c4f8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d h1:W07d4xkoAUSNOkOzdzXCdFGxT7o2rW4q8M34tB2i//k= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201030143252-cf7a54d06671/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201103235415-b653051172e4 h1:Qe0EMgvVYb6tmJhJHljCj3gS96hvSTkGNaIzp/ivq10= golang.org/x/tools v0.0.0-20201103235415-b653051172e4/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= @@ -1003,17 +1126,12 @@ google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0 h1:jz2KixHX7EcCPiQrySzPdnYT7DbINAypCqKZ1Z7GM40= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0 h1:J1Pl9P2lnmYFSJvgs70DKELqHNh8CNWXPbud4njEE2s= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0 h1:cG03eaksBzhfSIk7JRGctfp3lanklcOM/mTGvow7BbQ= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0 h1:jMF5hhVfMkTZwHW1SDpKq5CkgWLXOb31Foaca9Zr3oM= +google.golang.org/api v0.26.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0 h1:BaiDisFir8O4IJxvAabCGGkQ6yCJegNQqSVoYUNAnbk= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0 h1:yfrXXP61wVuLb0vBcG6qaOoIoqYEzOQS8jum51jkv2w= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/api v0.34.0 h1:k40adF3uR+6x/+hO5Dh4ZFUqFp67vxvbpafFiJxl10A= google.golang.org/api v0.34.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= @@ -1022,11 +1140,8 @@ google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= 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= @@ -1049,14 +1164,12 @@ google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940 h1:MRHtG0U6SnaUb+s+LhNE1qt1FQ1wlhqr5E4usBKC0uA= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200605102947-12044bf5ea91/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= @@ -1064,7 +1177,6 @@ google.golang.org/genproto v0.0.0-20200711021454-869866162049/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200715011427-11fb19a81f2c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 h1:PDIOdWxZ8eRizhKa1AAvY53xsvLB1cWorMjslvY3VA8= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201030142918-24207fddd1c3/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1083,18 +1195,12 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0 h1:bO/TA4OxCOummhSf10siHuG7vJOiwh7SpRpFZDkOgl4= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.32.0 h1:zWTV+LMdc3kaiJMSTOFz2UgSBgx8RNQoTGiZu3fR9S0= google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1 h1:DGeFlSan2f+WEtCERJ4J9GJWk15TxUi8QGagfI87Xyc= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.34.0 h1:raiipEjMOIC/TO2AvyTxP25XFdLxNIBwzDh3FM3XztI= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= @@ -1102,34 +1208,37 @@ google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLY google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0 h1:cJv5/xdbk1NnMPR1VP9+HU6gupuG9MLBoH1r6RHZ2MY= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 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 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 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 h1:RlWgLqCMMIYYEVcAR5MDsuHlVkaIPDAF+5Dehzg8L5A= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= 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/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/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= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1137,32 +1246,64 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c h1:grhR+C34yXImVGp7EzNk+DTIk+323eIUWOmEevy6bDo= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/postgres v1.0.5/go.mod h1:qrD92UurYzNctBMVCJ8C3VQEjffEuphycXtxOudXNCA= gorm.io/gorm v1.20.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.20.6/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= +k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA= +k8s.io/api v0.18.5 h1:fKbCxr+U3fu7k6jB+QeYPD/c6xKYeSJ2KVWmyUypuWM= +k8s.io/api v0.18.5/go.mod h1:tN+e/2nbdGKOAH55NMV8oGrMG+3uRlA9GaRfvnCCSNk= +k8s.io/apiextensions-apiserver v0.18.5 h1:pvbXjB/BRXZiO+/Erp5Pxr+lnhDCv5uxNxHh3FLGZ/g= +k8s.io/apiextensions-apiserver v0.18.5/go.mod h1:woZ7PkEIMHjhHIyApvOwkGOkBLUYKuet0VWVkPTQ/Fs= +k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= +k8s.io/apimachinery v0.18.5 h1:Lh6tgsM9FMkC12K5T5QjRm7rDs6aQN5JHkA0JomULDM= +k8s.io/apimachinery v0.18.5/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= +k8s.io/apiserver v0.18.5/go.mod h1:+1XgOMq7YJ3OyqPNSJ54EveHwCoBWcJT9CaPycYI5ps= +k8s.io/cli-runtime v0.18.3/go.mod h1:pqbbi4nqRIQhUWAVzen8uE8DD/zcZLwf+8sQYO4lwLk= +k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw= +k8s.io/client-go v0.18.5 h1:cLhGZdOmyPhwtt20Lrb7uAqxxB1uvY+NTmNJvno1oKA= +k8s.io/client-go v0.18.5/go.mod h1:EsiD+7Fx+bRckKWZXnAXRKKetm1WuzPagH4iOSC8x58= +k8s.io/code-generator v0.18.3/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= +k8s.io/code-generator v0.18.5/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= +k8s.io/component-base v0.18.3/go.mod h1:bp5GzGR0aGkYEfTj+eTY0AN/vXTgkJdQXjNTTVUaa3k= +k8s.io/component-base v0.18.5/go.mod h1:RSbcboNk4B+S8Acs2JaBOVW3XNz1+A637s2jL+QQrlU= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +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/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= +k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU= +k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= +sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= +vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= diff --git a/internal/admin/repository/eventsourcing/eventstore/administrator.go b/internal/admin/repository/eventsourcing/eventstore/administrator.go index b36717481e..a80b42574d 100644 --- a/internal/admin/repository/eventsourcing/eventstore/administrator.go +++ b/internal/admin/repository/eventsourcing/eventstore/administrator.go @@ -48,7 +48,7 @@ func (repo *AdministratorRepo) GetViews() ([]*view_model.View, error) { } func (repo *AdministratorRepo) GetSpoolerDiv(database, view string) int64 { - sequence, err := repo.View.GetCurrentSequence(database, view, "") + sequence, err := repo.View.GetCurrentSequence(database, view) if err != nil { return 0 diff --git a/internal/admin/repository/eventsourcing/eventstore/iam.go b/internal/admin/repository/eventsourcing/eventstore/iam.go index 515e752024..98878b6099 100644 --- a/internal/admin/repository/eventsourcing/eventstore/iam.go +++ b/internal/admin/repository/eventsourcing/eventstore/iam.go @@ -40,7 +40,7 @@ func (repo *IAMRepository) IAMMemberByID(ctx context.Context, iamID, userID stri func (repo *IAMRepository) SearchIAMMembers(ctx context.Context, request *iam_model.IAMMemberSearchRequest) (*iam_model.IAMMemberSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) - sequence, err := repo.View.GetLatestIAMMemberSequence("") + sequence, err := repo.View.GetLatestIAMMemberSequence() logging.Log("EVENT-Slkci").OnError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Warn("could not read latest iam sequence") members, count, err := repo.View.SearchIAMMembers(request) if err != nil { @@ -70,9 +70,7 @@ func (repo *IAMRepository) GetIAMMemberRoles() []string { } func (repo *IAMRepository) RemoveIDPConfig(ctx context.Context, idpConfigID string) error { - // if repo.IAMV2Command != nil { - // return repo.IAMV2Command. - // } + aggregates := make([]*es_models.Aggregate, 0) idp := iam_model.NewIDPConfig(repo.SystemDefaults.IamID, idpConfigID) _, agg, err := repo.IAMEventstore.PrepareRemoveIDPConfig(ctx, idp) @@ -115,7 +113,7 @@ func (repo *IAMRepository) RemoveIDPConfig(ctx context.Context, idpConfigID stri func (repo *IAMRepository) SearchIDPConfigs(ctx context.Context, request *iam_model.IDPConfigSearchRequest) (*iam_model.IDPConfigSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) - sequence, err := repo.View.GetLatestIDPConfigSequence("") + sequence, err := repo.View.GetLatestIDPConfigSequence() logging.Log("EVENT-Dk8si").OnError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Warn("could not read latest idp config sequence") idps, count, err := repo.View.SearchIDPConfigs(request) if err != nil { @@ -134,31 +132,6 @@ func (repo *IAMRepository) SearchIDPConfigs(ctx context.Context, request *iam_mo return result, nil } -func (repo *IAMRepository) GetDefaultLabelPolicy(ctx context.Context) (*iam_model.LabelPolicyView, error) { - policy, viewErr := repo.View.LabelPolicyByAggregateID(repo.SystemDefaults.IamID) - if viewErr != nil && !caos_errs.IsNotFound(viewErr) { - return nil, viewErr - } - if caos_errs.IsNotFound(viewErr) { - policy = new(iam_es_model.LabelPolicyView) - } - events, esErr := repo.IAMEventstore.IAMEventsByID(ctx, repo.SystemDefaults.IamID, policy.Sequence) - if caos_errs.IsNotFound(viewErr) && len(events) == 0 { - return nil, caos_errs.ThrowNotFound(nil, "EVENT-4bM0s", "Errors.IAM.LabelPolicy.NotFound") - } - if esErr != nil { - logging.Log("EVENT-3M0xs").WithError(esErr).Debug("error retrieving new events") - return iam_es_model.LabelPolicyViewToModel(policy), nil - } - policyCopy := *policy - for _, event := range events { - if err := policyCopy.AppendEvent(event); err != nil { - return iam_es_model.LabelPolicyViewToModel(policy), nil - } - } - return iam_es_model.LabelPolicyViewToModel(policy), nil -} - func (repo *IAMRepository) GetDefaultLoginPolicy(ctx context.Context) (*iam_model.LoginPolicyView, error) { policy, viewErr := repo.View.LoginPolicyByAggregateID(repo.SystemDefaults.IamID) if viewErr != nil && !caos_errs.IsNotFound(viewErr) { @@ -187,7 +160,7 @@ func (repo *IAMRepository) GetDefaultLoginPolicy(ctx context.Context) (*iam_mode func (repo *IAMRepository) SearchDefaultIDPProviders(ctx context.Context, request *iam_model.IDPProviderSearchRequest) (*iam_model.IDPProviderSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) request.AppendAggregateIDQuery(repo.SystemDefaults.IamID) - sequence, err := repo.View.GetLatestIDPProviderSequence("") + sequence, err := repo.View.GetLatestIDPProviderSequence() logging.Log("EVENT-Tuiks").OnError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Warn("could not read latest iam sequence") providers, count, err := repo.View.SearchIDPProviders(request) if err != nil { @@ -352,3 +325,97 @@ func (repo *IAMRepository) GetOrgIAMPolicy(ctx context.Context) (*iam_model.OrgI } return iam_es_model.OrgIAMViewToModel(policy), nil } + +func (repo *IAMRepository) AddDefaultOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) { + policy.AggregateID = repo.SystemDefaults.IamID + return repo.IAMEventstore.AddOrgIAMPolicy(ctx, policy) +} + +func (repo *IAMRepository) ChangeDefaultOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) { + policy.AggregateID = repo.SystemDefaults.IamID + return repo.IAMEventstore.ChangeOrgIAMPolicy(ctx, policy) +} + +func (repo *IAMRepository) GetDefaultLabelPolicy(ctx context.Context) (*iam_model.LabelPolicyView, error) { + policy, err := repo.View.LabelPolicyByAggregateID(repo.SystemDefaults.IamID) + if err != nil { + return nil, err + } + return iam_es_model.LabelPolicyViewToModel(policy), err +} + +func (repo *IAMRepository) AddDefaultLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) { + policy.AggregateID = repo.SystemDefaults.IamID + return repo.IAMEventstore.AddLabelPolicy(ctx, policy) +} + +func (repo *IAMRepository) ChangeDefaultLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) { + policy.AggregateID = repo.SystemDefaults.IamID + return repo.IAMEventstore.ChangeLabelPolicy(ctx, policy) +} + +func (repo *IAMRepository) GetDefaultMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error) { + template, err := repo.View.MailTemplateByAggregateID(repo.SystemDefaults.IamID) + if err != nil { + return nil, err + } + return iam_es_model.MailTemplateViewToModel(template), err +} + +func (repo *IAMRepository) AddDefaultMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) { + template.AggregateID = repo.SystemDefaults.IamID + return repo.IAMEventstore.AddMailTemplate(ctx, template) +} + +func (repo *IAMRepository) ChangeDefaultMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) { + template.AggregateID = repo.SystemDefaults.IamID + return repo.IAMEventstore.ChangeMailTemplate(ctx, template) +} + +func (repo *IAMRepository) SearchIAMMembersx(ctx context.Context, request *iam_model.IAMMemberSearchRequest) (*iam_model.IAMMemberSearchResponse, error) { + request.EnsureLimit(repo.SearchLimit) + sequence, err := repo.View.GetLatestIAMMemberSequence() + logging.Log("EVENT-Slkci").OnError(err).Warn("could not read latest iam sequence") + members, count, err := repo.View.SearchIAMMembers(request) + if err != nil { + return nil, err + } + result := &iam_model.IAMMemberSearchResponse{ + Offset: request.Offset, + Limit: request.Limit, + TotalResult: count, + Result: iam_es_model.IAMMembersToModel(members), + } + if err == nil { + result.Sequence = sequence.CurrentSequence + result.Timestamp = result.Timestamp + } + return result, nil +} + +func (repo *IAMRepository) GetDefaultMailTexts(ctx context.Context) (*iam_model.MailTextsView, error) { + text, err := repo.View.MailTexts(repo.SystemDefaults.IamID) + if err != nil { + return nil, err + } + return iam_es_model.MailTextsViewToModel(text, true), err +} + +func (repo *IAMRepository) GetDefaultMailText(ctx context.Context, textType string, language string) (*iam_model.MailTextView, error) { + text, err := repo.View.MailTextByIDs(repo.SystemDefaults.IamID, textType, language) + if err != nil { + return nil, err + } + text.Default = true + return iam_es_model.MailTextViewToModel(text), err +} + +func (repo *IAMRepository) AddDefaultMailText(ctx context.Context, text *iam_model.MailText) (*iam_model.MailText, error) { + text.AggregateID = repo.SystemDefaults.IamID + return repo.IAMEventstore.AddMailText(ctx, text) +} + +func (repo *IAMRepository) ChangeDefaultMailText(ctx context.Context, text *iam_model.MailText) (*iam_model.MailText, error) { + text.AggregateID = repo.SystemDefaults.IamID + return repo.IAMEventstore.ChangeMailText(ctx, text) +} diff --git a/internal/admin/repository/eventsourcing/eventstore/org.go b/internal/admin/repository/eventsourcing/eventstore/org.go index 59718f45be..78400eae29 100644 --- a/internal/admin/repository/eventsourcing/eventstore/org.go +++ b/internal/admin/repository/eventsourcing/eventstore/org.go @@ -87,7 +87,7 @@ func (repo *OrgRepo) OrgByID(ctx context.Context, id string) (*org_model.Org, er func (repo *OrgRepo) SearchOrgs(ctx context.Context, query *org_model.OrgSearchRequest) (*org_model.OrgSearchResult, error) { query.EnsureLimit(repo.SearchLimit) - sequence, err := repo.View.GetLatestOrgSequence("") + sequence, err := repo.View.GetLatestOrgSequence() logging.Log("EVENT-LXo9w").OnError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Warn("could not read latest iam sequence") orgs, count, err := repo.View.SearchOrgs(query) if err != nil { diff --git a/internal/admin/repository/eventsourcing/handler/handler.go b/internal/admin/repository/eventsourcing/handler/handler.go index ed0e60f6ed..041c1a7720 100644 --- a/internal/admin/repository/eventsourcing/handler/handler.go +++ b/internal/admin/repository/eventsourcing/handler/handler.go @@ -74,6 +74,10 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es defaults, repos.IamEvents, repos.OrgEvents), + newMailTemplate( + handler{view, bulkLimit, configs.cycleDuration("MailTemplate"), errorCount, es}), + newMailText( + handler{view, bulkLimit, configs.cycleDuration("MailText"), errorCount, es}), } } diff --git a/internal/admin/repository/eventsourcing/handler/iam_member.go b/internal/admin/repository/eventsourcing/handler/iam_member.go index 79aafcf055..438fd0263b 100644 --- a/internal/admin/repository/eventsourcing/handler/iam_member.go +++ b/internal/admin/repository/eventsourcing/handler/iam_member.go @@ -45,8 +45,8 @@ func (m *IAMMember) subscribe() { }() } -func (m *IAMMember) CurrentSequence(event *es_models.Event) (uint64, error) { - sequence, err := m.view.GetLatestIAMMemberSequence(string(event.AggregateType)) +func (m *IAMMember) CurrentSequence() (uint64, error) { + sequence, err := m.view.GetLatestIAMMemberSequence() if err != nil { return 0, err } @@ -62,7 +62,7 @@ func (m *IAMMember) AggregateTypes() []es_models.AggregateType { } func (m *IAMMember) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := m.view.GetLatestIAMMemberSequence("") + sequence, err := m.view.GetLatestIAMMemberSequence() if err != nil { return nil, err } diff --git a/internal/admin/repository/eventsourcing/handler/idp_config.go b/internal/admin/repository/eventsourcing/handler/idp_config.go index bf0dc97104..7368b5f4ce 100644 --- a/internal/admin/repository/eventsourcing/handler/idp_config.go +++ b/internal/admin/repository/eventsourcing/handler/idp_config.go @@ -47,8 +47,8 @@ func (i *IDPConfig) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{model.IAMAggregate} } -func (i *IDPConfig) CurrentSequence(event *es_models.Event) (uint64, error) { - sequence, err := i.view.GetLatestIDPConfigSequence(string(event.AggregateType)) +func (i *IDPConfig) CurrentSequence() (uint64, error) { + sequence, err := i.view.GetLatestIDPConfigSequence() if err != nil { return 0, err } @@ -56,7 +56,7 @@ func (i *IDPConfig) CurrentSequence(event *es_models.Event) (uint64, error) { } func (i *IDPConfig) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := i.view.GetLatestIDPConfigSequence("") + sequence, err := i.view.GetLatestIDPConfigSequence() if err != nil { return nil, err } diff --git a/internal/admin/repository/eventsourcing/handler/idp_providers.go b/internal/admin/repository/eventsourcing/handler/idp_providers.go index 06c44c4c0a..59956f6f76 100644 --- a/internal/admin/repository/eventsourcing/handler/idp_providers.go +++ b/internal/admin/repository/eventsourcing/handler/idp_providers.go @@ -64,8 +64,8 @@ func (i *IDPProvider) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{model.IAMAggregate, org_es_model.OrgAggregate} } -func (i *IDPProvider) CurrentSequence(event *es_models.Event) (uint64, error) { - sequence, err := i.view.GetLatestIDPProviderSequence(string(event.AggregateType)) +func (i *IDPProvider) CurrentSequence() (uint64, error) { + sequence, err := i.view.GetLatestIDPProviderSequence() if err != nil { return 0, err } @@ -73,7 +73,7 @@ func (i *IDPProvider) CurrentSequence(event *es_models.Event) (uint64, error) { } func (i *IDPProvider) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := i.view.GetLatestIDPProviderSequence("") + sequence, err := i.view.GetLatestIDPProviderSequence() if err != nil { return nil, err } diff --git a/internal/admin/repository/eventsourcing/handler/label_policy.go b/internal/admin/repository/eventsourcing/handler/label_policy.go index c1604fba69..50bf98a2d2 100644 --- a/internal/admin/repository/eventsourcing/handler/label_policy.go +++ b/internal/admin/repository/eventsourcing/handler/label_policy.go @@ -47,7 +47,7 @@ func (p *LabelPolicy) AggregateTypes() []es_models.AggregateType { } func (p *LabelPolicy) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := p.view.GetLatestLabelPolicySequence("") + sequence, err := p.view.GetLatestLabelPolicySequence() if err != nil { return nil, err } @@ -56,8 +56,8 @@ func (p *LabelPolicy) EventQuery() (*es_models.SearchQuery, error) { LatestSequenceFilter(sequence.CurrentSequence), nil } -func (p *LabelPolicy) CurrentSequence(event *es_models.Event) (uint64, error) { - sequence, err := p.view.GetLatestLabelPolicySequence(string(event.AggregateType)) +func (p *LabelPolicy) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestLabelPolicySequence() if err != nil { return 0, err } diff --git a/internal/admin/repository/eventsourcing/handler/login_policy.go b/internal/admin/repository/eventsourcing/handler/login_policy.go index 032f2a4349..aaf1f5b197 100644 --- a/internal/admin/repository/eventsourcing/handler/login_policy.go +++ b/internal/admin/repository/eventsourcing/handler/login_policy.go @@ -48,7 +48,7 @@ func (p *LoginPolicy) AggregateTypes() []models.AggregateType { } func (p *LoginPolicy) EventQuery() (*models.SearchQuery, error) { - sequence, err := p.view.GetLatestLoginPolicySequence("") + sequence, err := p.view.GetLatestLoginPolicySequence() if err != nil { return nil, err } @@ -57,8 +57,8 @@ func (p *LoginPolicy) EventQuery() (*models.SearchQuery, error) { LatestSequenceFilter(sequence.CurrentSequence), nil } -func (p *LoginPolicy) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestLoginPolicySequence(string(event.AggregateType)) +func (p *LoginPolicy) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestLoginPolicySequence() if err != nil { return 0, err } diff --git a/internal/admin/repository/eventsourcing/handler/mail_template.go b/internal/admin/repository/eventsourcing/handler/mail_template.go new file mode 100644 index 0000000000..c140ba1022 --- /dev/null +++ b/internal/admin/repository/eventsourcing/handler/mail_template.go @@ -0,0 +1,105 @@ +package handler + +import ( + "github.com/caos/logging" + + "github.com/caos/zitadel/internal/eventstore" + "github.com/caos/zitadel/internal/eventstore/models" + es_models "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/eventstore/query" + "github.com/caos/zitadel/internal/eventstore/spooler" + "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" + iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" + iam_model "github.com/caos/zitadel/internal/iam/repository/view/model" +) + +type MailTemplate struct { + handler + subscription *eventstore.Subscription +} + +func newMailTemplate(handler handler) *MailTemplate { + h := &MailTemplate{ + handler: handler, + } + + h.subscribe() + + return h +} + +func (m *MailTemplate) subscribe() { + m.subscription = m.es.Subscribe(m.AggregateTypes()...) + go func() { + for event := range m.subscription.Events { + query.ReduceEvent(m, event) + } + }() +} + +const ( + mailTemplateTable = "adminapi.mail_templates" +) + +func (m *MailTemplate) ViewModel() string { + return mailTemplateTable +} + +func (_ *MailTemplate) AggregateTypes() []es_models.AggregateType { + return []es_models.AggregateType{iam_es_model.IAMAggregate} +} + +func (p *MailTemplate) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestMailTemplateSequence() + if err != nil { + return 0, err + } + return sequence.CurrentSequence, nil +} + +func (m *MailTemplate) EventQuery() (*models.SearchQuery, error) { + sequence, err := m.view.GetLatestMailTemplateSequence() + if err != nil { + return nil, err + } + return es_models.NewSearchQuery(). + AggregateTypeFilter(m.AggregateTypes()...). + LatestSequenceFilter(sequence.CurrentSequence), nil +} + +func (m *MailTemplate) Reduce(event *models.Event) (err error) { + switch event.AggregateType { + case model.IAMAggregate: + err = m.processMailTemplate(event) + } + return err +} + +func (m *MailTemplate) processMailTemplate(event *models.Event) (err error) { + template := new(iam_model.MailTemplateView) + switch event.Type { + case model.MailTemplateAdded: + err = template.AppendEvent(event) + case model.MailTemplateChanged: + template, err = m.view.MailTemplateByAggregateID(event.AggregateID) + if err != nil { + return err + } + err = template.AppendEvent(event) + default: + return m.view.ProcessedMailTemplateSequence(event) + } + if err != nil { + return err + } + return m.view.PutMailTemplate(template, event) +} + +func (m *MailTemplate) OnError(event *models.Event, err error) error { + logging.LogWithFields("SPOOL-Wj8sf", "id", event.AggregateID).WithError(err).Warn("something went wrong in label template handler") + return spooler.HandleError(event, err, m.view.GetLatestMailTemplateFailedEvent, m.view.ProcessedMailTemplateFailedEvent, m.view.ProcessedMailTemplateSequence, m.errorCountUntilSkip) +} + +func (o *MailTemplate) OnSuccess() error { + return spooler.HandleSuccess(o.view.UpdateMailTemplateSpoolerRunTimestamp) +} diff --git a/internal/admin/repository/eventsourcing/handler/mail_text.go b/internal/admin/repository/eventsourcing/handler/mail_text.go new file mode 100644 index 0000000000..6462bd54db --- /dev/null +++ b/internal/admin/repository/eventsourcing/handler/mail_text.go @@ -0,0 +1,109 @@ +package handler + +import ( + "github.com/caos/logging" + + "github.com/caos/zitadel/internal/eventstore" + "github.com/caos/zitadel/internal/eventstore/models" + es_models "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/eventstore/query" + "github.com/caos/zitadel/internal/eventstore/spooler" + "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" + iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" + iam_model "github.com/caos/zitadel/internal/iam/repository/view/model" +) + +type MailText struct { + handler + subscription *eventstore.Subscription +} + +func newMailText(handler handler) *MailText { + h := &MailText{ + handler: handler, + } + + h.subscribe() + + return h +} + +func (m *MailText) subscribe() { + m.subscription = m.es.Subscribe(m.AggregateTypes()...) + go func() { + for event := range m.subscription.Events { + query.ReduceEvent(m, event) + } + }() +} + +const ( + mailTextTable = "adminapi.mail_texts" +) + +func (m *MailText) ViewModel() string { + return mailTextTable +} + +func (_ *MailText) AggregateTypes() []es_models.AggregateType { + return []es_models.AggregateType{iam_es_model.IAMAggregate} +} + +func (p *MailText) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestMailTextSequence() + if err != nil { + return 0, err + } + return sequence.CurrentSequence, nil +} + +func (m *MailText) EventQuery() (*models.SearchQuery, error) { + sequence, err := m.view.GetLatestMailTextSequence() + if err != nil { + return nil, err + } + return es_models.NewSearchQuery(). + AggregateTypeFilter(m.AggregateTypes()...). + LatestSequenceFilter(sequence.CurrentSequence), nil +} + +func (m *MailText) Reduce(event *models.Event) (err error) { + switch event.AggregateType { + case model.IAMAggregate: + err = m.processMailText(event) + } + return err +} + +func (m *MailText) processMailText(event *models.Event) (err error) { + mailText := new(iam_model.MailTextView) + switch event.Type { + case model.MailTextAdded: + err = mailText.AppendEvent(event) + case model.MailTextChanged: + err = mailText.SetData(event) + if err != nil { + return err + } + mailText, err = m.view.MailTextByIDs(event.AggregateID, mailText.MailTextType, mailText.Language) + if err != nil { + return err + } + err = mailText.AppendEvent(event) + default: + return m.view.ProcessedMailTextSequence(event) + } + if err != nil { + return err + } + return m.view.PutMailText(mailText, event) +} + +func (m *MailText) OnError(event *models.Event, err error) error { + logging.LogWithFields("HANDL-5jk84", "id", event.AggregateID).WithError(err).Warn("something went wrong in label mailText handler") + return spooler.HandleError(event, err, m.view.GetLatestMailTextFailedEvent, m.view.ProcessedMailTextFailedEvent, m.view.ProcessedMailTextSequence, m.errorCountUntilSkip) +} + +func (o *MailText) OnSuccess() error { + return spooler.HandleSuccess(o.view.UpdateMailTextSpoolerRunTimestamp) +} diff --git a/internal/admin/repository/eventsourcing/handler/org.go b/internal/admin/repository/eventsourcing/handler/org.go index 02ace32943..128eab554a 100644 --- a/internal/admin/repository/eventsourcing/handler/org.go +++ b/internal/admin/repository/eventsourcing/handler/org.go @@ -49,15 +49,15 @@ func (o *Org) AggregateTypes() []es_models.AggregateType { } func (o *Org) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := o.view.GetLatestOrgSequence("") + sequence, err := o.view.GetLatestOrgSequence() if err != nil { return nil, err } return eventsourcing.OrgQuery(sequence.CurrentSequence), nil } -func (o *Org) CurrentSequence(event *es_models.Event) (uint64, error) { - sequence, err := o.view.GetLatestOrgSequence(string(event.AggregateType)) +func (o *Org) CurrentSequence() (uint64, error) { + sequence, err := o.view.GetLatestOrgSequence() if err != nil { return 0, err } diff --git a/internal/admin/repository/eventsourcing/handler/org_iam_policy.go b/internal/admin/repository/eventsourcing/handler/org_iam_policy.go index a98db79c09..660a0a25a3 100644 --- a/internal/admin/repository/eventsourcing/handler/org_iam_policy.go +++ b/internal/admin/repository/eventsourcing/handler/org_iam_policy.go @@ -48,7 +48,7 @@ func (p *OrgIAMPolicy) AggregateTypes() []es_models.AggregateType { } func (p *OrgIAMPolicy) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := p.view.GetLatestOrgIAMPolicySequence("") + sequence, err := p.view.GetLatestOrgIAMPolicySequence() if err != nil { return nil, err } @@ -57,8 +57,8 @@ func (p *OrgIAMPolicy) EventQuery() (*es_models.SearchQuery, error) { LatestSequenceFilter(sequence.CurrentSequence), nil } -func (p *OrgIAMPolicy) CurrentSequence(event *es_models.Event) (uint64, error) { - sequence, err := p.view.GetLatestOrgIAMPolicySequence(string(event.AggregateType)) +func (p *OrgIAMPolicy) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestOrgIAMPolicySequence() if err != nil { return 0, err } diff --git a/internal/admin/repository/eventsourcing/handler/password_age_policy.go b/internal/admin/repository/eventsourcing/handler/password_age_policy.go index 7cfa1b2bb2..692d5a578c 100644 --- a/internal/admin/repository/eventsourcing/handler/password_age_policy.go +++ b/internal/admin/repository/eventsourcing/handler/password_age_policy.go @@ -49,8 +49,8 @@ func (p *PasswordAgePolicy) AggregateTypes() []models.AggregateType { return []models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate} } -func (p *PasswordAgePolicy) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestPasswordAgePolicySequence(string(event.AggregateType)) +func (p *PasswordAgePolicy) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestPasswordAgePolicySequence() if err != nil { return 0, err } @@ -58,7 +58,7 @@ func (p *PasswordAgePolicy) CurrentSequence(event *models.Event) (uint64, error) } func (p *PasswordAgePolicy) EventQuery() (*models.SearchQuery, error) { - sequence, err := p.view.GetLatestPasswordAgePolicySequence("") + sequence, err := p.view.GetLatestPasswordAgePolicySequence() if err != nil { return nil, err } diff --git a/internal/admin/repository/eventsourcing/handler/password_complexity_policy.go b/internal/admin/repository/eventsourcing/handler/password_complexity_policy.go index edab685d23..2408af543f 100644 --- a/internal/admin/repository/eventsourcing/handler/password_complexity_policy.go +++ b/internal/admin/repository/eventsourcing/handler/password_complexity_policy.go @@ -49,8 +49,8 @@ func (p *PasswordComplexityPolicy) AggregateTypes() []models.AggregateType { return []models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate} } -func (p *PasswordComplexityPolicy) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestPasswordComplexityPolicySequence(string(event.AggregateType)) +func (p *PasswordComplexityPolicy) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestPasswordComplexityPolicySequence() if err != nil { return 0, err } @@ -58,7 +58,7 @@ func (p *PasswordComplexityPolicy) CurrentSequence(event *models.Event) (uint64, } func (p *PasswordComplexityPolicy) EventQuery() (*models.SearchQuery, error) { - sequence, err := p.view.GetLatestPasswordComplexityPolicySequence("") + sequence, err := p.view.GetLatestPasswordComplexityPolicySequence() if err != nil { return nil, err } diff --git a/internal/admin/repository/eventsourcing/handler/password_lockout_policy.go b/internal/admin/repository/eventsourcing/handler/password_lockout_policy.go index 99a8393cb8..979dba7b89 100644 --- a/internal/admin/repository/eventsourcing/handler/password_lockout_policy.go +++ b/internal/admin/repository/eventsourcing/handler/password_lockout_policy.go @@ -49,8 +49,8 @@ func (p *PasswordLockoutPolicy) AggregateTypes() []models.AggregateType { return []models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate} } -func (p *PasswordLockoutPolicy) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestPasswordLockoutPolicySequence(string(event.AggregateType)) +func (p *PasswordLockoutPolicy) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestPasswordLockoutPolicySequence() if err != nil { return 0, err } @@ -58,7 +58,7 @@ func (p *PasswordLockoutPolicy) CurrentSequence(event *models.Event) (uint64, er } func (p *PasswordLockoutPolicy) EventQuery() (*models.SearchQuery, error) { - sequence, err := p.view.GetLatestPasswordLockoutPolicySequence("") + sequence, err := p.view.GetLatestPasswordLockoutPolicySequence() if err != nil { return nil, err } diff --git a/internal/admin/repository/eventsourcing/handler/user.go b/internal/admin/repository/eventsourcing/handler/user.go index eb3a4bd83f..0c568128b3 100644 --- a/internal/admin/repository/eventsourcing/handler/user.go +++ b/internal/admin/repository/eventsourcing/handler/user.go @@ -68,8 +68,8 @@ func (u *User) AggregateTypes() []models.AggregateType { return []models.AggregateType{es_model.UserAggregate, org_es_model.OrgAggregate} } -func (u *User) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := u.view.GetLatestUserSequence(string(event.AggregateType)) +func (u *User) CurrentSequence() (uint64, error) { + sequence, err := u.view.GetLatestUserSequence() if err != nil { return 0, err } @@ -77,7 +77,7 @@ func (u *User) CurrentSequence(event *models.Event) (uint64, error) { } func (u *User) EventQuery() (*models.SearchQuery, error) { - sequence, err := u.view.GetLatestUserSequence("") + sequence, err := u.view.GetLatestUserSequence() if err != nil { return nil, err } diff --git a/internal/admin/repository/eventsourcing/handler/user_external_idps.go b/internal/admin/repository/eventsourcing/handler/user_external_idps.go index f7719e601b..1368fa1bc8 100644 --- a/internal/admin/repository/eventsourcing/handler/user_external_idps.go +++ b/internal/admin/repository/eventsourcing/handler/user_external_idps.go @@ -69,8 +69,8 @@ func (i *ExternalIDP) AggregateTypes() []models.AggregateType { return []models.AggregateType{model.UserAggregate, iam_es_model.IAMAggregate, org_es_model.OrgAggregate} } -func (i *ExternalIDP) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := i.view.GetLatestExternalIDPSequence(string(event.AggregateType)) +func (i *ExternalIDP) CurrentSequence() (uint64, error) { + sequence, err := i.view.GetLatestExternalIDPSequence() if err != nil { return 0, err } @@ -78,7 +78,7 @@ func (i *ExternalIDP) CurrentSequence(event *models.Event) (uint64, error) { } func (i *ExternalIDP) EventQuery() (*models.SearchQuery, error) { - sequence, err := i.view.GetLatestExternalIDPSequence("") + sequence, err := i.view.GetLatestExternalIDPSequence() if err != nil { return nil, err } diff --git a/internal/admin/repository/eventsourcing/view/external_idps.go b/internal/admin/repository/eventsourcing/view/external_idps.go index 384c1d81d0..6b9a239b23 100644 --- a/internal/admin/repository/eventsourcing/view/external_idps.go +++ b/internal/admin/repository/eventsourcing/view/external_idps.go @@ -65,8 +65,8 @@ func (v *View) DeleteExternalIDPsByUserID(userID string, event *models.Event) er return v.ProcessedExternalIDPSequence(event) } -func (v *View) GetLatestExternalIDPSequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(externalIDPTable, aggregateType) +func (v *View) GetLatestExternalIDPSequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(externalIDPTable) } func (v *View) ProcessedExternalIDPSequence(event *models.Event) error { diff --git a/internal/admin/repository/eventsourcing/view/iam_member.go b/internal/admin/repository/eventsourcing/view/iam_member.go index d215ca0b5b..21cc782b6d 100644 --- a/internal/admin/repository/eventsourcing/view/iam_member.go +++ b/internal/admin/repository/eventsourcing/view/iam_member.go @@ -57,8 +57,8 @@ func (v *View) DeleteIAMMembersByUserID(userID string, event *models.Event) erro return v.ProcessedIAMMemberSequence(event) } -func (v *View) GetLatestIAMMemberSequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(iamMemberTable, aggregateType) +func (v *View) GetLatestIAMMemberSequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(iamMemberTable) } func (v *View) ProcessedIAMMemberSequence(event *models.Event) error { diff --git a/internal/admin/repository/eventsourcing/view/idp_configs.go b/internal/admin/repository/eventsourcing/view/idp_configs.go index 5a120de265..deb4e688cc 100644 --- a/internal/admin/repository/eventsourcing/view/idp_configs.go +++ b/internal/admin/repository/eventsourcing/view/idp_configs.go @@ -37,8 +37,8 @@ func (v *View) DeleteIDPConfig(idpID string, event *models.Event) error { return v.ProcessedIDPConfigSequence(event) } -func (v *View) GetLatestIDPConfigSequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(idpConfigTable, aggregateType) +func (v *View) GetLatestIDPConfigSequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(idpConfigTable) } func (v *View) ProcessedIDPConfigSequence(event *models.Event) error { diff --git a/internal/admin/repository/eventsourcing/view/idp_providers.go b/internal/admin/repository/eventsourcing/view/idp_providers.go index 26a682379d..7d0ef141fb 100644 --- a/internal/admin/repository/eventsourcing/view/idp_providers.go +++ b/internal/admin/repository/eventsourcing/view/idp_providers.go @@ -49,8 +49,8 @@ func (v *View) DeleteIDPProvider(aggregateID, idpConfigID string, event *models. return v.ProcessedIDPProviderSequence(event) } -func (v *View) GetLatestIDPProviderSequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(idpProviderTable, aggregateType) +func (v *View) GetLatestIDPProviderSequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(idpProviderTable) } func (v *View) ProcessedIDPProviderSequence(event *models.Event) error { diff --git a/internal/admin/repository/eventsourcing/view/label_policies.go b/internal/admin/repository/eventsourcing/view/label_policies.go index 9b1a46cee1..761fc2c62f 100644 --- a/internal/admin/repository/eventsourcing/view/label_policies.go +++ b/internal/admin/repository/eventsourcing/view/label_policies.go @@ -23,8 +23,8 @@ func (v *View) PutLabelPolicy(policy *model.LabelPolicyView, event *models.Event return v.ProcessedLabelPolicySequence(event) } -func (v *View) GetLatestLabelPolicySequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(labelPolicyTable, aggregateType) +func (v *View) GetLatestLabelPolicySequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(labelPolicyTable) } func (v *View) ProcessedLabelPolicySequence(event *models.Event) error { diff --git a/internal/admin/repository/eventsourcing/view/login_policies.go b/internal/admin/repository/eventsourcing/view/login_policies.go index 7e71983724..8785e8df24 100644 --- a/internal/admin/repository/eventsourcing/view/login_policies.go +++ b/internal/admin/repository/eventsourcing/view/login_policies.go @@ -32,8 +32,8 @@ func (v *View) DeleteLoginPolicy(aggregateID string, event *models.Event) error return v.ProcessedLoginPolicySequence(event) } -func (v *View) GetLatestLoginPolicySequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(loginPolicyTable, aggregateType) +func (v *View) GetLatestLoginPolicySequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(loginPolicyTable) } func (v *View) ProcessedLoginPolicySequence(event *models.Event) error { diff --git a/internal/admin/repository/eventsourcing/view/mail_templates.go b/internal/admin/repository/eventsourcing/view/mail_templates.go new file mode 100644 index 0000000000..a6ec850ab8 --- /dev/null +++ b/internal/admin/repository/eventsourcing/view/mail_templates.go @@ -0,0 +1,44 @@ +package view + +import ( + "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/iam/repository/view" + "github.com/caos/zitadel/internal/iam/repository/view/model" + global_view "github.com/caos/zitadel/internal/view/repository" +) + +const ( + mailTemplateTable = "adminapi.mail_templates" +) + +func (v *View) MailTemplateByAggregateID(aggregateID string) (*model.MailTemplateView, error) { + return view.GetMailTemplateByAggregateID(v.Db, mailTemplateTable, aggregateID) +} + +func (v *View) PutMailTemplate(template *model.MailTemplateView, event *models.Event) error { + err := view.PutMailTemplate(v.Db, mailTemplateTable, template) + if err != nil { + return err + } + return v.ProcessedMailTemplateSequence(event) +} + +func (v *View) GetLatestMailTemplateSequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(mailTemplateTable) +} + +func (v *View) ProcessedMailTemplateSequence(event *models.Event) error { + return v.saveCurrentSequence(mailTemplateTable, event) +} + +func (v *View) UpdateMailTemplateSpoolerRunTimestamp() error { + return v.updateSpoolerRunSequence(mailTemplateTable) +} + +func (v *View) GetLatestMailTemplateFailedEvent(sequence uint64) (*global_view.FailedEvent, error) { + return v.latestFailedEvent(mailTemplateTable, sequence) +} + +func (v *View) ProcessedMailTemplateFailedEvent(failedEvent *global_view.FailedEvent) error { + return v.saveFailedEvent(failedEvent) +} diff --git a/internal/admin/repository/eventsourcing/view/mail_texts.go b/internal/admin/repository/eventsourcing/view/mail_texts.go new file mode 100644 index 0000000000..89d67fea6d --- /dev/null +++ b/internal/admin/repository/eventsourcing/view/mail_texts.go @@ -0,0 +1,48 @@ +package view + +import ( + "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/iam/repository/view" + "github.com/caos/zitadel/internal/iam/repository/view/model" + global_view "github.com/caos/zitadel/internal/view/repository" +) + +const ( + mailTextTable = "adminapi.mail_texts" +) + +func (v *View) MailTexts(aggregateID string) ([]*model.MailTextView, error) { + return view.GetMailTexts(v.Db, mailTextTable, aggregateID) +} + +func (v *View) MailTextByIDs(aggregateID string, textType string, language string) (*model.MailTextView, error) { + return view.GetMailTextByIDs(v.Db, mailTextTable, aggregateID, textType, language) +} + +func (v *View) PutMailText(template *model.MailTextView, event *models.Event) error { + err := view.PutMailText(v.Db, mailTextTable, template) + if err != nil { + return err + } + return v.ProcessedMailTextSequence(event) +} + +func (v *View) GetLatestMailTextSequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(mailTextTable) +} + +func (v *View) ProcessedMailTextSequence(event *models.Event) error { + return v.saveCurrentSequence(mailTextTable, event) +} + +func (v *View) UpdateMailTextSpoolerRunTimestamp() error { + return v.updateSpoolerRunSequence(mailTextTable) +} + +func (v *View) GetLatestMailTextFailedEvent(sequence uint64) (*global_view.FailedEvent, error) { + return v.latestFailedEvent(mailTextTable, sequence) +} + +func (v *View) ProcessedMailTextFailedEvent(failedEvent *global_view.FailedEvent) error { + return v.saveFailedEvent(failedEvent) +} diff --git a/internal/admin/repository/eventsourcing/view/org.go b/internal/admin/repository/eventsourcing/view/org.go index b5d104a7ed..a5d2d45ab2 100644 --- a/internal/admin/repository/eventsourcing/view/org.go +++ b/internal/admin/repository/eventsourcing/view/org.go @@ -40,8 +40,8 @@ func (v *View) UpdateOrgSpoolerRunTimestamp() error { return v.updateSpoolerRunSequence(orgTable) } -func (v *View) GetLatestOrgSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(orgTable, aggregateType) +func (v *View) GetLatestOrgSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(orgTable) } func (v *View) ProcessedOrgSequence(event *models.Event) error { diff --git a/internal/admin/repository/eventsourcing/view/org_iam_policy.go b/internal/admin/repository/eventsourcing/view/org_iam_policy.go index 5d13779e48..5e77383407 100644 --- a/internal/admin/repository/eventsourcing/view/org_iam_policy.go +++ b/internal/admin/repository/eventsourcing/view/org_iam_policy.go @@ -32,8 +32,8 @@ func (v *View) DeleteOrgIAMPolicy(aggregateID string, event *models.Event) error return v.ProcessedOrgIAMPolicySequence(event) } -func (v *View) GetLatestOrgIAMPolicySequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(orgIAMPolicyTable, aggregateType) +func (v *View) GetLatestOrgIAMPolicySequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(orgIAMPolicyTable) } func (v *View) ProcessedOrgIAMPolicySequence(event *models.Event) error { diff --git a/internal/admin/repository/eventsourcing/view/password_age_policy.go b/internal/admin/repository/eventsourcing/view/password_age_policy.go index b1cbe535c4..02fe19db3c 100644 --- a/internal/admin/repository/eventsourcing/view/password_age_policy.go +++ b/internal/admin/repository/eventsourcing/view/password_age_policy.go @@ -32,8 +32,8 @@ func (v *View) DeletePasswordAgePolicy(aggregateID string, event *models.Event) return v.ProcessedPasswordAgePolicySequence(event) } -func (v *View) GetLatestPasswordAgePolicySequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(passwordAgePolicyTable, aggregateType) +func (v *View) GetLatestPasswordAgePolicySequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(passwordAgePolicyTable) } func (v *View) ProcessedPasswordAgePolicySequence(event *models.Event) error { diff --git a/internal/admin/repository/eventsourcing/view/password_complexity_policy.go b/internal/admin/repository/eventsourcing/view/password_complexity_policy.go index 44315b9666..9d7e315e04 100644 --- a/internal/admin/repository/eventsourcing/view/password_complexity_policy.go +++ b/internal/admin/repository/eventsourcing/view/password_complexity_policy.go @@ -32,8 +32,8 @@ func (v *View) DeletePasswordComplexityPolicy(aggregateID string, event *models. return v.ProcessedPasswordComplexityPolicySequence(event) } -func (v *View) GetLatestPasswordComplexityPolicySequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(passwordComplexityPolicyTable, aggregateType) +func (v *View) GetLatestPasswordComplexityPolicySequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(passwordComplexityPolicyTable) } func (v *View) ProcessedPasswordComplexityPolicySequence(event *models.Event) error { diff --git a/internal/admin/repository/eventsourcing/view/password_lockout_policy.go b/internal/admin/repository/eventsourcing/view/password_lockout_policy.go index 805aab3fc3..6076320aea 100644 --- a/internal/admin/repository/eventsourcing/view/password_lockout_policy.go +++ b/internal/admin/repository/eventsourcing/view/password_lockout_policy.go @@ -32,8 +32,8 @@ func (v *View) DeletePasswordLockoutPolicy(aggregateID string, event *models.Eve return v.ProcessedPasswordLockoutPolicySequence(event) } -func (v *View) GetLatestPasswordLockoutPolicySequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(passwordLockoutPolicyTable, aggregateType) +func (v *View) GetLatestPasswordLockoutPolicySequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(passwordLockoutPolicyTable) } func (v *View) ProcessedPasswordLockoutPolicySequence(event *models.Event) error { diff --git a/internal/admin/repository/eventsourcing/view/sequence.go b/internal/admin/repository/eventsourcing/view/sequence.go index 5915da9b56..358e2daf61 100644 --- a/internal/admin/repository/eventsourcing/view/sequence.go +++ b/internal/admin/repository/eventsourcing/view/sequence.go @@ -12,11 +12,11 @@ const ( ) func (v *View) saveCurrentSequence(viewName string, event *models.Event) error { - return repository.SaveCurrentSequence(v.Db, sequencesTable, viewName, string(event.AggregateType), event.Sequence, event.CreationDate) + return repository.SaveCurrentSequence(v.Db, sequencesTable, viewName, event.Sequence, event.CreationDate) } -func (v *View) latestSequence(viewName, aggregateType string) (*repository.CurrentSequence, error) { - return repository.LatestSequence(v.Db, sequencesTable, viewName, aggregateType) +func (v *View) latestSequence(viewName string) (*repository.CurrentSequence, error) { + return repository.LatestSequence(v.Db, sequencesTable, viewName) } func (v *View) AllCurrentSequences(db string) ([]*repository.CurrentSequence, error) { @@ -24,7 +24,7 @@ func (v *View) AllCurrentSequences(db string) ([]*repository.CurrentSequence, er } func (v *View) updateSpoolerRunSequence(viewName string) error { - currentSequence, err := repository.LatestSequence(v.Db, sequencesTable, viewName, "") + currentSequence, err := repository.LatestSequence(v.Db, sequencesTable, viewName) if err != nil { return err } @@ -38,10 +38,10 @@ func (v *View) updateSpoolerRunSequence(viewName string) error { return repository.UpdateCurrentSequence(v.Db, sequencesTable, currentSequence) } -func (v *View) GetCurrentSequence(db, viewName, aggregateType string) (*repository.CurrentSequence, error) { +func (v *View) GetCurrentSequence(db, viewName string) (*repository.CurrentSequence, error) { sequenceTable := db + ".current_sequences" fullView := db + "." + viewName - return repository.LatestSequence(v.Db, sequenceTable, fullView, aggregateType) + return repository.LatestSequence(v.Db, sequenceTable, fullView) } func (v *View) ClearView(db, viewName string) error { diff --git a/internal/admin/repository/eventsourcing/view/user.go b/internal/admin/repository/eventsourcing/view/user.go index 9694b41f78..3a5c8d064c 100644 --- a/internal/admin/repository/eventsourcing/view/user.go +++ b/internal/admin/repository/eventsourcing/view/user.go @@ -65,8 +65,8 @@ func (v *View) DeleteUser(userID string, event *models.Event) error { return v.ProcessedUserSequence(event) } -func (v *View) GetLatestUserSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(userTable, aggregateType) +func (v *View) GetLatestUserSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(userTable) } func (v *View) ProcessedUserSequence(event *models.Event) error { diff --git a/internal/admin/repository/iam.go b/internal/admin/repository/iam.go index 4c045ab935..b2ca0c6fa6 100644 --- a/internal/admin/repository/iam.go +++ b/internal/admin/repository/iam.go @@ -20,6 +20,15 @@ type IAMRepository interface { GetDefaultLabelPolicy(ctx context.Context) (*iam_model.LabelPolicyView, error) + GetDefaultMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error) + AddDefaultMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) + ChangeDefaultMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) + + GetDefaultMailTexts(ctx context.Context) (*iam_model.MailTextsView, error) + GetDefaultMailText(ctx context.Context, textType string, language string) (*iam_model.MailTextView, error) + AddDefaultMailText(ctx context.Context, mailText *iam_model.MailText) (*iam_model.MailText, error) + ChangeDefaultMailText(ctx context.Context, policy *iam_model.MailText) (*iam_model.MailText, error) + GetDefaultPasswordComplexityPolicy(ctx context.Context) (*iam_model.PasswordComplexityPolicyView, error) GetDefaultPasswordAgePolicy(ctx context.Context) (*iam_model.PasswordAgePolicyView, error) diff --git a/internal/api/grpc/admin/template.go b/internal/api/grpc/admin/template.go new file mode 100644 index 0000000000..8e4d4b25d4 --- /dev/null +++ b/internal/api/grpc/admin/template.go @@ -0,0 +1,24 @@ +package admin + +import ( + "context" + + "github.com/caos/zitadel/pkg/grpc/admin" + "github.com/golang/protobuf/ptypes/empty" +) + +func (s *Server) GetDefaultMailTemplate(ctx context.Context, _ *empty.Empty) (*admin.DefaultMailTemplateView, error) { + result, err := s.iam.GetDefaultMailTemplate(ctx) + if err != nil { + return nil, err + } + return templateViewFromModel(result), nil +} + +func (s *Server) UpdateDefaultMailTemplate(ctx context.Context, policy *admin.DefaultMailTemplateUpdate) (*admin.DefaultMailTemplate, error) { + result, err := s.iam.ChangeDefaultMailTemplate(ctx, templateToModel(policy)) + if err != nil { + return nil, err + } + return templateFromModel(result), nil +} diff --git a/internal/api/grpc/admin/template_converter.go b/internal/api/grpc/admin/template_converter.go new file mode 100644 index 0000000000..c4c8b65967 --- /dev/null +++ b/internal/api/grpc/admin/template_converter.go @@ -0,0 +1,42 @@ +package admin + +import ( + "github.com/caos/logging" + iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/pkg/grpc/admin" + "github.com/golang/protobuf/ptypes" +) + +func templateToModel(policy *admin.DefaultMailTemplateUpdate) *iam_model.MailTemplate { + return &iam_model.MailTemplate{ + Template: policy.Template, + } +} + +func templateFromModel(policy *iam_model.MailTemplate) *admin.DefaultMailTemplate { + creationDate, err := ptypes.TimestampProto(policy.CreationDate) + logging.Log("ADMIN-CAA7T").OnError(err).Debug("date parse failed") + + changeDate, err := ptypes.TimestampProto(policy.ChangeDate) + logging.Log("ADMIN-H52Zx").OnError(err).Debug("date parse failed") + + return &admin.DefaultMailTemplate{ + Template: policy.Template, + CreationDate: creationDate, + ChangeDate: changeDate, + } +} + +func templateViewFromModel(policy *iam_model.MailTemplateView) *admin.DefaultMailTemplateView { + creationDate, err := ptypes.TimestampProto(policy.CreationDate) + logging.Log("ADMIN-yWFs5").OnError(err).Debug("date parse failed") + + changeDate, err := ptypes.TimestampProto(policy.ChangeDate) + logging.Log("ADMIN-JRpIO").OnError(err).Debug("date parse failed") + + return &admin.DefaultMailTemplateView{ + Template: policy.Template, + CreationDate: creationDate, + ChangeDate: changeDate, + } +} diff --git a/internal/api/grpc/admin/text.go b/internal/api/grpc/admin/text.go new file mode 100644 index 0000000000..5f053de0e9 --- /dev/null +++ b/internal/api/grpc/admin/text.go @@ -0,0 +1,32 @@ +package admin + +import ( + "context" + + "github.com/caos/zitadel/pkg/grpc/admin" + "github.com/golang/protobuf/ptypes/empty" +) + +func (s *Server) GetDefaultMailTexts(ctx context.Context, _ *empty.Empty) (*admin.DefaultMailTextsView, error) { + result, err := s.iam.GetDefaultMailTexts(ctx) + if err != nil { + return nil, err + } + return textsViewFromModel(result), nil +} + +func (s *Server) GetDefaultMailText(ctx context.Context, textType string, language string) (*admin.DefaultMailTextView, error) { + result, err := s.iam.GetDefaultMailText(ctx, textType, language) + if err != nil { + return nil, err + } + return textViewFromModel(result), nil +} + +func (s *Server) UpdateDefaultMailText(ctx context.Context, text *admin.DefaultMailTextUpdate) (*admin.DefaultMailText, error) { + result, err := s.iam.ChangeDefaultMailText(ctx, textToModel(text)) + if err != nil { + return nil, err + } + return textFromModel(result), nil +} diff --git a/internal/api/grpc/admin/text_converter.go b/internal/api/grpc/admin/text_converter.go new file mode 100644 index 0000000000..20b4052b29 --- /dev/null +++ b/internal/api/grpc/admin/text_converter.go @@ -0,0 +1,78 @@ +package admin + +import ( + "github.com/caos/logging" + iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/pkg/grpc/admin" + "github.com/golang/protobuf/ptypes" +) + +func textToModel(text *admin.DefaultMailTextUpdate) *iam_model.MailText { + return &iam_model.MailText{ + MailTextType: text.MailTextType, + Language: text.Language, + Title: text.Title, + PreHeader: text.PreHeader, + Subject: text.Subject, + Greeting: text.Greeting, + Text: text.Text, + ButtonText: text.ButtonText, + } +} + +func textFromModel(text *iam_model.MailText) *admin.DefaultMailText { + creationDate, err := ptypes.TimestampProto(text.CreationDate) + logging.Log("ADMIN-Jlzsj").OnError(err).Debug("date parse failed") + + changeDate, err := ptypes.TimestampProto(text.ChangeDate) + logging.Log("ADMIN-mw5b8").OnError(err).Debug("date parse failed") + + return &admin.DefaultMailText{ + MailTextType: text.MailTextType, + Language: text.Language, + Title: text.Title, + PreHeader: text.PreHeader, + Subject: text.Subject, + Greeting: text.Greeting, + Text: text.Text, + ButtonText: text.ButtonText, + CreationDate: creationDate, + ChangeDate: changeDate, + } +} + +func textsViewFromModel(textsin *iam_model.MailTextsView) *admin.DefaultMailTextsView { + return &admin.DefaultMailTextsView{ + Texts: textsViewToModel(textsin.Texts), + } +} + +func textsViewToModel(queries []*iam_model.MailTextView) []*admin.DefaultMailTextView { + modelQueries := make([]*admin.DefaultMailTextView, len(queries)) + for i, query := range queries { + modelQueries[i] = textViewFromModel(query) + } + + return modelQueries +} + +func textViewFromModel(text *iam_model.MailTextView) *admin.DefaultMailTextView { + creationDate, err := ptypes.TimestampProto(text.CreationDate) + logging.Log("ADMIN-7RyJc").OnError(err).Debug("date parse failed") + + changeDate, err := ptypes.TimestampProto(text.ChangeDate) + logging.Log("ADMIN-fTFgY").OnError(err).Debug("date parse failed") + + return &admin.DefaultMailTextView{ + MailTextType: text.MailTextType, + Language: text.Language, + Title: text.Title, + PreHeader: text.PreHeader, + Subject: text.Subject, + Greeting: text.Greeting, + Text: text.Text, + ButtonText: text.ButtonText, + CreationDate: creationDate, + ChangeDate: changeDate, + } +} diff --git a/internal/api/grpc/management/mail_template.go b/internal/api/grpc/management/mail_template.go new file mode 100644 index 0000000000..290b1534ab --- /dev/null +++ b/internal/api/grpc/management/mail_template.go @@ -0,0 +1,45 @@ +package management + +import ( + "context" + + "github.com/caos/zitadel/pkg/grpc/management" + "github.com/golang/protobuf/ptypes/empty" +) + +func (s *Server) GetMailTemplate(ctx context.Context, _ *empty.Empty) (*management.MailTemplateView, error) { + result, err := s.org.GetMailTemplate(ctx) + if err != nil { + return nil, err + } + return mailTemplateViewFromModel(result), nil +} + +func (s *Server) GetDefaultMailTemplate(ctx context.Context, _ *empty.Empty) (*management.MailTemplateView, error) { + result, err := s.org.GetDefaultMailTemplate(ctx) + if err != nil { + return nil, err + } + return mailTemplateViewFromModel(result), nil +} + +func (s *Server) CreateMailTemplate(ctx context.Context, template *management.MailTemplateUpdate) (*management.MailTemplate, error) { + result, err := s.org.AddMailTemplate(ctx, mailTemplateRequestToModel(template)) + if err != nil { + return nil, err + } + return mailTemplateFromModel(result), nil +} + +func (s *Server) UpdateMailTemplate(ctx context.Context, template *management.MailTemplateUpdate) (*management.MailTemplate, error) { + result, err := s.org.ChangeMailTemplate(ctx, mailTemplateRequestToModel(template)) + if err != nil { + return nil, err + } + return mailTemplateFromModel(result), nil +} + +func (s *Server) RemoveMailTemplate(ctx context.Context, _ *empty.Empty) (*empty.Empty, error) { + err := s.org.RemoveMailTemplate(ctx) + return &empty.Empty{}, err +} diff --git a/internal/api/grpc/management/mail_template_converter.go b/internal/api/grpc/management/mail_template_converter.go new file mode 100644 index 0000000000..a4e9dffa70 --- /dev/null +++ b/internal/api/grpc/management/mail_template_converter.go @@ -0,0 +1,42 @@ +package management + +import ( + "github.com/caos/logging" + iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/pkg/grpc/management" + "github.com/golang/protobuf/ptypes" +) + +func mailTemplateRequestToModel(mailTemplate *management.MailTemplateUpdate) *iam_model.MailTemplate { + return &iam_model.MailTemplate{ + Template: mailTemplate.Template, + } +} + +func mailTemplateFromModel(mailTemplate *iam_model.MailTemplate) *management.MailTemplate { + creationDate, err := ptypes.TimestampProto(mailTemplate.CreationDate) + logging.Log("MANAG-ULKZ6").OnError(err).Debug("date parse failed") + + changeDate, err := ptypes.TimestampProto(mailTemplate.ChangeDate) + logging.Log("MANAG-451rI").OnError(err).Debug("date parse failed") + return &management.MailTemplate{ + Template: mailTemplate.Template, + CreationDate: creationDate, + ChangeDate: changeDate, + } +} + +func mailTemplateViewFromModel(mailTemplate *iam_model.MailTemplateView) *management.MailTemplateView { + creationDate, err := ptypes.TimestampProto(mailTemplate.CreationDate) + logging.Log("MANAG-koQnB").OnError(err).Debug("date parse failed") + + changeDate, err := ptypes.TimestampProto(mailTemplate.ChangeDate) + logging.Log("MANAG-ToDhD").OnError(err).Debug("date parse failed") + + return &management.MailTemplateView{ + Default: mailTemplate.Default, + Template: mailTemplate.Template, + CreationDate: creationDate, + ChangeDate: changeDate, + } +} diff --git a/internal/api/grpc/management/mail_text.go b/internal/api/grpc/management/mail_text.go new file mode 100644 index 0000000000..1d9928a1cd --- /dev/null +++ b/internal/api/grpc/management/mail_text.go @@ -0,0 +1,45 @@ +package management + +import ( + "context" + + "github.com/caos/zitadel/pkg/grpc/management" + "github.com/golang/protobuf/ptypes/empty" +) + +func (s *Server) GetMailTexts(ctx context.Context, _ *empty.Empty) (*management.MailTextsView, error) { + result, err := s.org.GetMailTexts(ctx) + if err != nil { + return nil, err + } + return mailTextsViewFromModel(result.Texts), nil +} + +func (s *Server) GetDefaultMailTexts(ctx context.Context, _ *empty.Empty) (*management.MailTextsView, error) { + result, err := s.org.GetDefaultMailTexts(ctx) + if err != nil { + return nil, err + } + return mailTextsViewFromModel(result.Texts), nil +} + +func (s *Server) CreateMailText(ctx context.Context, mailText *management.MailTextUpdate) (*management.MailText, error) { + result, err := s.org.AddMailText(ctx, mailTextRequestToModel(mailText)) + if err != nil { + return nil, err + } + return mailTextFromModel(result), nil +} + +func (s *Server) UpdateMailText(ctx context.Context, mailText *management.MailTextUpdate) (*management.MailText, error) { + result, err := s.org.ChangeMailText(ctx, mailTextRequestToModel(mailText)) + if err != nil { + return nil, err + } + return mailTextFromModel(result), nil +} + +func (s *Server) RemoveMailText(ctx context.Context, mailText *management.MailTextRemove) (*empty.Empty, error) { + err := s.org.RemoveMailText(ctx, mailTextRemoveToModel(mailText)) + return &empty.Empty{}, err +} diff --git a/internal/api/grpc/management/mail_text_converter.go b/internal/api/grpc/management/mail_text_converter.go new file mode 100644 index 0000000000..8b4e580e01 --- /dev/null +++ b/internal/api/grpc/management/mail_text_converter.go @@ -0,0 +1,82 @@ +package management + +import ( + "github.com/caos/logging" + iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/pkg/grpc/management" + "github.com/golang/protobuf/ptypes" +) + +func mailTextRequestToModel(mailText *management.MailTextUpdate) *iam_model.MailText { + return &iam_model.MailText{ + MailTextType: mailText.MailTextType, + Language: mailText.Language, + Title: mailText.Title, + PreHeader: mailText.PreHeader, + Subject: mailText.Subject, + Greeting: mailText.Greeting, + Text: mailText.Text, + ButtonText: mailText.ButtonText, + } +} + +func mailTextRemoveToModel(mailText *management.MailTextRemove) *iam_model.MailText { + return &iam_model.MailText{ + MailTextType: mailText.MailTextType, + Language: mailText.Language, + } +} + +func mailTextFromModel(mailText *iam_model.MailText) *management.MailText { + creationDate, err := ptypes.TimestampProto(mailText.CreationDate) + logging.Log("MANAG-ULKZ6").OnError(err).Debug("date parse failed") + + changeDate, err := ptypes.TimestampProto(mailText.ChangeDate) + logging.Log("MANAG-451rI").OnError(err).Debug("date parse failed") + + return &management.MailText{ + MailTextType: mailText.MailTextType, + Language: mailText.Language, + Title: mailText.Title, + PreHeader: mailText.PreHeader, + Subject: mailText.Subject, + Greeting: mailText.Greeting, + Text: mailText.Text, + ButtonText: mailText.ButtonText, + CreationDate: creationDate, + ChangeDate: changeDate, + } +} + +func mailTextsViewFromModel(queries []*iam_model.MailTextView) *management.MailTextsView { + modelQueries := make([]*management.MailTextView, len(queries)) + for i, query := range queries { + modelQueries[i] = mailTextViewFromModel(query) + } + + return &management.MailTextsView{ + Texts: modelQueries, + } +} + +func mailTextViewFromModel(mailText *iam_model.MailTextView) *management.MailTextView { + creationDate, err := ptypes.TimestampProto(mailText.CreationDate) + logging.Log("MANAG-koQnB").OnError(err).Debug("date parse failed") + + changeDate, err := ptypes.TimestampProto(mailText.ChangeDate) + logging.Log("MANAG-ToDhD").OnError(err).Debug("date parse failed") + + return &management.MailTextView{ + Default: mailText.Default, + MailTextType: mailText.MailTextType, + Language: mailText.Language, + Title: mailText.Title, + PreHeader: mailText.PreHeader, + Subject: mailText.Subject, + Greeting: mailText.Greeting, + Text: mailText.Text, + ButtonText: mailText.ButtonText, + CreationDate: creationDate, + ChangeDate: changeDate, + } +} diff --git a/internal/api/grpc/management/project_converter.go b/internal/api/grpc/management/project_converter.go index 9b3f1e6fe6..9dbfcce553 100644 --- a/internal/api/grpc/management/project_converter.go +++ b/internal/api/grpc/management/project_converter.go @@ -94,10 +94,13 @@ func projectRoleViewsFromModel(roles []*proj_model.ProjectRoleView) []*managemen func projectRoleViewFromModel(role *proj_model.ProjectRoleView) *management.ProjectRoleView { creationDate, err := ptypes.TimestampProto(role.CreationDate) logging.Log("GRPC-dlso3").OnError(err).Debug("unable to parse timestamp") + changeDate, err := ptypes.TimestampProto(role.ChangeDate) + logging.Log("MANAG-BRr8Y").OnError(err).Debug("unable to parse timestamp") return &management.ProjectRoleView{ ProjectId: role.ProjectID, CreationDate: creationDate, + ChangeDate: changeDate, Key: role.Key, Group: role.Group, DisplayName: role.DisplayName, diff --git a/internal/auth/repository/eventsourcing/eventstore/org.go b/internal/auth/repository/eventsourcing/eventstore/org.go index 9339b1be70..c5f3ecced0 100644 --- a/internal/auth/repository/eventsourcing/eventstore/org.go +++ b/internal/auth/repository/eventsourcing/eventstore/org.go @@ -36,7 +36,7 @@ type OrgRepository struct { func (repo *OrgRepository) SearchOrgs(ctx context.Context, request *org_model.OrgSearchRequest) (*org_model.OrgSearchResult, error) { request.EnsureLimit(repo.SearchLimit) - sequence, err := repo.View.GetLatestOrgSequence("") + sequence, err := repo.View.GetLatestOrgSequence() logging.Log("EVENT-7Udhz").OnError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Warn("could not read latest org sequence") members, count, err := repo.View.SearchOrgs(request) if err != nil { diff --git a/internal/auth/repository/eventsourcing/eventstore/user.go b/internal/auth/repository/eventsourcing/eventstore/user.go index b831f81865..66248090fa 100644 --- a/internal/auth/repository/eventsourcing/eventstore/user.go +++ b/internal/auth/repository/eventsourcing/eventstore/user.go @@ -94,7 +94,7 @@ func (repo *UserRepo) MyProfile(ctx context.Context) (*model.Profile, error) { func (repo *UserRepo) SearchMyExternalIDPs(ctx context.Context, request *model.ExternalIDPSearchRequest) (*model.ExternalIDPSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) - sequence, seqErr := repo.View.GetLatestExternalIDPSequence("") + sequence, seqErr := repo.View.GetLatestExternalIDPSequence() logging.Log("EVENT-5Jsi8").OnError(seqErr).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Warn("could not read latest user sequence") request.AppendUserQuery(authz.GetCtxData(ctx).UserID) externalIDPS, count, err := repo.View.SearchExternalIDPs(request) diff --git a/internal/auth/repository/eventsourcing/eventstore/user_grant.go b/internal/auth/repository/eventsourcing/eventstore/user_grant.go index d9ba6bc842..cba39e4314 100644 --- a/internal/auth/repository/eventsourcing/eventstore/user_grant.go +++ b/internal/auth/repository/eventsourcing/eventstore/user_grant.go @@ -29,7 +29,7 @@ type UserGrantRepo struct { func (repo *UserGrantRepo) SearchMyUserGrants(ctx context.Context, request *grant_model.UserGrantSearchRequest) (*grant_model.UserGrantSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) - sequence, err := repo.View.GetLatestUserGrantSequence("") + sequence, err := repo.View.GetLatestUserGrantSequence() logging.Log("EVENT-Hd7s3").OnError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Warn("could not read latest user grant sequence") request.Queries = append(request.Queries, &grant_model.UserGrantSearchQuery{Key: grant_model.UserGrantSearchKeyUserID, Method: global_model.SearchMethodEquals, Value: authz.GetCtxData(ctx).UserID}) grants, count, err := repo.View.SearchUserGrants(request) diff --git a/internal/auth/repository/eventsourcing/handler/application.go b/internal/auth/repository/eventsourcing/handler/application.go index 5a8d5d41ff..f8bd45d33a 100644 --- a/internal/auth/repository/eventsourcing/handler/application.go +++ b/internal/auth/repository/eventsourcing/handler/application.go @@ -53,7 +53,7 @@ func (_ *Application) AggregateTypes() []models.AggregateType { return []models.AggregateType{es_model.ProjectAggregate} } -func (a *Application) CurrentSequence(event *models.Event) (uint64, error) { +func (a *Application) CurrentSequence() (uint64, error) { sequence, err := a.view.GetLatestApplicationSequence() if err != nil { return 0, err diff --git a/internal/auth/repository/eventsourcing/handler/idp_config.go b/internal/auth/repository/eventsourcing/handler/idp_config.go index b070d89c8a..d11ee66219 100644 --- a/internal/auth/repository/eventsourcing/handler/idp_config.go +++ b/internal/auth/repository/eventsourcing/handler/idp_config.go @@ -49,8 +49,8 @@ func (_ *IDPConfig) AggregateTypes() []models.AggregateType { return []models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate} } -func (i *IDPConfig) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := i.view.GetLatestIDPConfigSequence(string(event.AggregateType)) +func (i *IDPConfig) CurrentSequence() (uint64, error) { + sequence, err := i.view.GetLatestIDPConfigSequence() if err != nil { return 0, err } @@ -58,7 +58,7 @@ func (i *IDPConfig) CurrentSequence(event *models.Event) (uint64, error) { } func (i *IDPConfig) EventQuery() (*models.SearchQuery, error) { - sequence, err := i.view.GetLatestIDPConfigSequence("") + sequence, err := i.view.GetLatestIDPConfigSequence() if err != nil { return nil, err } diff --git a/internal/auth/repository/eventsourcing/handler/idp_providers.go b/internal/auth/repository/eventsourcing/handler/idp_providers.go index 8622fc57b1..77e372cd41 100644 --- a/internal/auth/repository/eventsourcing/handler/idp_providers.go +++ b/internal/auth/repository/eventsourcing/handler/idp_providers.go @@ -66,8 +66,8 @@ func (_ *IDPProvider) AggregateTypes() []models.AggregateType { return []models.AggregateType{model.IAMAggregate, org_es_model.OrgAggregate} } -func (i *IDPProvider) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := i.view.GetLatestIDPProviderSequence(string(event.AggregateType)) +func (i *IDPProvider) CurrentSequence() (uint64, error) { + sequence, err := i.view.GetLatestIDPProviderSequence() if err != nil { return 0, err } @@ -75,7 +75,7 @@ func (i *IDPProvider) CurrentSequence(event *models.Event) (uint64, error) { } func (i *IDPProvider) EventQuery() (*models.SearchQuery, error) { - sequence, err := i.view.GetLatestIDPProviderSequence("") + sequence, err := i.view.GetLatestIDPProviderSequence() if err != nil { return nil, err } diff --git a/internal/auth/repository/eventsourcing/handler/key.go b/internal/auth/repository/eventsourcing/handler/key.go index 54703a2509..ded3ce7685 100644 --- a/internal/auth/repository/eventsourcing/handler/key.go +++ b/internal/auth/repository/eventsourcing/handler/key.go @@ -49,8 +49,8 @@ func (_ *Key) AggregateTypes() []models.AggregateType { return []models.AggregateType{es_model.KeyPairAggregate} } -func (k *Key) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := k.view.GetLatestKeySequence(string(event.AggregateType)) +func (k *Key) CurrentSequence() (uint64, error) { + sequence, err := k.view.GetLatestKeySequence() if err != nil { return 0, err } @@ -58,7 +58,7 @@ func (k *Key) CurrentSequence(event *models.Event) (uint64, error) { } func (k *Key) EventQuery() (*models.SearchQuery, error) { - sequence, err := k.view.GetLatestKeySequence("") + sequence, err := k.view.GetLatestKeySequence() if err != nil { return nil, err } diff --git a/internal/auth/repository/eventsourcing/handler/login_policy.go b/internal/auth/repository/eventsourcing/handler/login_policy.go index 35700d80c7..be964781c3 100644 --- a/internal/auth/repository/eventsourcing/handler/login_policy.go +++ b/internal/auth/repository/eventsourcing/handler/login_policy.go @@ -49,8 +49,8 @@ func (_ *LoginPolicy) AggregateTypes() []models.AggregateType { return []models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate} } -func (p *LoginPolicy) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestLoginPolicySequence(string(event.AggregateType)) +func (p *LoginPolicy) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestLoginPolicySequence() if err != nil { return 0, err } @@ -58,7 +58,7 @@ func (p *LoginPolicy) CurrentSequence(event *models.Event) (uint64, error) { } func (p *LoginPolicy) EventQuery() (*models.SearchQuery, error) { - sequence, err := p.view.GetLatestLoginPolicySequence("") + sequence, err := p.view.GetLatestLoginPolicySequence() if err != nil { return nil, err } diff --git a/internal/auth/repository/eventsourcing/handler/machine_keys.go b/internal/auth/repository/eventsourcing/handler/machine_keys.go index 0ca0532c26..bf877564af 100644 --- a/internal/auth/repository/eventsourcing/handler/machine_keys.go +++ b/internal/auth/repository/eventsourcing/handler/machine_keys.go @@ -6,7 +6,6 @@ import ( "github.com/caos/logging" "github.com/caos/zitadel/internal/eventstore" - "github.com/caos/zitadel/internal/eventstore/models" es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/eventstore/query" "github.com/caos/zitadel/internal/eventstore/spooler" @@ -50,8 +49,8 @@ func (_ *MachineKeys) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{model.UserAggregate} } -func (k *MachineKeys) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := k.view.GetLatestMachineKeySequence(string(event.AggregateType)) +func (k *MachineKeys) CurrentSequence() (uint64, error) { + sequence, err := k.view.GetLatestMachineKeySequence() if err != nil { return 0, err } @@ -59,7 +58,7 @@ func (k *MachineKeys) CurrentSequence(event *models.Event) (uint64, error) { } func (k *MachineKeys) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := k.view.GetLatestMachineKeySequence("") + sequence, err := k.view.GetLatestMachineKeySequence() if err != nil { return nil, err } diff --git a/internal/auth/repository/eventsourcing/handler/org.go b/internal/auth/repository/eventsourcing/handler/org.go index ea87eed2f2..5a92125004 100644 --- a/internal/auth/repository/eventsourcing/handler/org.go +++ b/internal/auth/repository/eventsourcing/handler/org.go @@ -4,7 +4,6 @@ import ( "github.com/caos/logging" "github.com/caos/zitadel/internal/eventstore" - "github.com/caos/zitadel/internal/eventstore/models" es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/eventstore/query" "github.com/caos/zitadel/internal/eventstore/spooler" @@ -49,8 +48,8 @@ func (_ *Org) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{model.OrgAggregate} } -func (o *Org) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := o.view.GetLatestOrgSequence(string(event.AggregateType)) +func (o *Org) CurrentSequence() (uint64, error) { + sequence, err := o.view.GetLatestOrgSequence() if err != nil { return 0, err } @@ -58,7 +57,7 @@ func (o *Org) CurrentSequence(event *models.Event) (uint64, error) { } func (o *Org) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := o.view.GetLatestOrgSequence("") + sequence, err := o.view.GetLatestOrgSequence() if err != nil { return nil, err } diff --git a/internal/auth/repository/eventsourcing/handler/org_iam_policy.go b/internal/auth/repository/eventsourcing/handler/org_iam_policy.go index 9d9d230a96..cfeae902f0 100644 --- a/internal/auth/repository/eventsourcing/handler/org_iam_policy.go +++ b/internal/auth/repository/eventsourcing/handler/org_iam_policy.go @@ -2,8 +2,8 @@ package handler import ( "github.com/caos/logging" + "github.com/caos/zitadel/internal/eventstore" - "github.com/caos/zitadel/internal/eventstore/models" es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/eventstore/query" "github.com/caos/zitadel/internal/eventstore/spooler" @@ -48,8 +48,8 @@ func (_ *OrgIAMPolicy) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{org_es_model.OrgAggregate, iam_es_model.IAMAggregate} } -func (p *OrgIAMPolicy) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestOrgIAMPolicySequence(string(event.AggregateType)) +func (p *OrgIAMPolicy) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestOrgIAMPolicySequence() if err != nil { return 0, err } @@ -57,7 +57,7 @@ func (p *OrgIAMPolicy) CurrentSequence(event *models.Event) (uint64, error) { } func (p *OrgIAMPolicy) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := p.view.GetLatestOrgIAMPolicySequence("") + sequence, err := p.view.GetLatestOrgIAMPolicySequence() if err != nil { return nil, err } diff --git a/internal/auth/repository/eventsourcing/handler/password_complexity_policy.go b/internal/auth/repository/eventsourcing/handler/password_complexity_policy.go index 65a86676a8..5cb9a5267b 100644 --- a/internal/auth/repository/eventsourcing/handler/password_complexity_policy.go +++ b/internal/auth/repository/eventsourcing/handler/password_complexity_policy.go @@ -2,8 +2,8 @@ package handler import ( "github.com/caos/logging" + "github.com/caos/zitadel/internal/eventstore" - "github.com/caos/zitadel/internal/eventstore/models" es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/eventstore/query" "github.com/caos/zitadel/internal/eventstore/spooler" @@ -48,8 +48,8 @@ func (_ *PasswordComplexityPolicy) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{org_es_model.OrgAggregate, iam_es_model.IAMAggregate} } -func (p *PasswordComplexityPolicy) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestPasswordComplexityPolicySequence(string(event.AggregateType)) +func (p *PasswordComplexityPolicy) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestPasswordComplexityPolicySequence() if err != nil { return 0, err } @@ -57,7 +57,7 @@ func (p *PasswordComplexityPolicy) CurrentSequence(event *models.Event) (uint64, } func (p *PasswordComplexityPolicy) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := p.view.GetLatestPasswordComplexityPolicySequence("") + sequence, err := p.view.GetLatestPasswordComplexityPolicySequence() if err != nil { return nil, err } diff --git a/internal/auth/repository/eventsourcing/handler/project_role.go b/internal/auth/repository/eventsourcing/handler/project_role.go index 5ee8722bdc..518516e7bb 100644 --- a/internal/auth/repository/eventsourcing/handler/project_role.go +++ b/internal/auth/repository/eventsourcing/handler/project_role.go @@ -2,8 +2,8 @@ package handler import ( "github.com/caos/logging" + "github.com/caos/zitadel/internal/eventstore" - "github.com/caos/zitadel/internal/eventstore/models" es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/eventstore/query" "github.com/caos/zitadel/internal/eventstore/spooler" @@ -54,8 +54,8 @@ func (_ *ProjectRole) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{model.ProjectAggregate} } -func (p *ProjectRole) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestProjectRoleSequence(string(event.AggregateType)) +func (p *ProjectRole) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestProjectRoleSequence() if err != nil { return 0, err } @@ -63,7 +63,7 @@ func (p *ProjectRole) CurrentSequence(event *models.Event) (uint64, error) { } func (p *ProjectRole) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := p.view.GetLatestProjectRoleSequence("") + sequence, err := p.view.GetLatestProjectRoleSequence() if err != nil { return nil, err } @@ -84,6 +84,7 @@ func (p *ProjectRole) Reduce(event *es_models.Event) (err error) { if err != nil { return err } + role.ChangeDate = event.CreationDate err = role.AppendEvent(event) case model.ProjectRoleRemoved: err = role.SetData(event) diff --git a/internal/auth/repository/eventsourcing/handler/token.go b/internal/auth/repository/eventsourcing/handler/token.go index b98e811bda..6a365580ac 100644 --- a/internal/auth/repository/eventsourcing/handler/token.go +++ b/internal/auth/repository/eventsourcing/handler/token.go @@ -58,8 +58,8 @@ func (_ *Token) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{user_es_model.UserAggregate, project_es_model.ProjectAggregate} } -func (p *Token) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestTokenSequence(string(event.AggregateType)) +func (p *Token) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestTokenSequence() if err != nil { return 0, err } @@ -67,7 +67,7 @@ func (p *Token) CurrentSequence(event *models.Event) (uint64, error) { } func (t *Token) EventQuery() (*models.SearchQuery, error) { - sequence, err := t.view.GetLatestTokenSequence("") + sequence, err := t.view.GetLatestTokenSequence() if err != nil { return nil, err } diff --git a/internal/auth/repository/eventsourcing/handler/user.go b/internal/auth/repository/eventsourcing/handler/user.go index f960ab720d..d87f8c3a2b 100644 --- a/internal/auth/repository/eventsourcing/handler/user.go +++ b/internal/auth/repository/eventsourcing/handler/user.go @@ -64,8 +64,8 @@ func (_ *User) AggregateTypes() []models.AggregateType { return []models.AggregateType{es_model.UserAggregate, org_es_model.OrgAggregate} } -func (u *User) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := u.view.GetLatestUserSequence(string(event.AggregateType)) +func (u *User) CurrentSequence() (uint64, error) { + sequence, err := u.view.GetLatestUserSequence() if err != nil { return 0, err } @@ -73,7 +73,7 @@ func (u *User) CurrentSequence(event *models.Event) (uint64, error) { } func (u *User) EventQuery() (*models.SearchQuery, error) { - sequence, err := u.view.GetLatestUserSequence("") + sequence, err := u.view.GetLatestUserSequence() if err != nil { return nil, err } diff --git a/internal/auth/repository/eventsourcing/handler/user_external_idps.go b/internal/auth/repository/eventsourcing/handler/user_external_idps.go index 8dcaebe3cb..2744137a79 100644 --- a/internal/auth/repository/eventsourcing/handler/user_external_idps.go +++ b/internal/auth/repository/eventsourcing/handler/user_external_idps.go @@ -68,8 +68,8 @@ func (_ *ExternalIDP) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{model.UserAggregate, iam_es_model.IAMAggregate, org_es_model.OrgAggregate} } -func (i *ExternalIDP) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := i.view.GetLatestExternalIDPSequence(string(event.AggregateType)) +func (i *ExternalIDP) CurrentSequence() (uint64, error) { + sequence, err := i.view.GetLatestExternalIDPSequence() if err != nil { return 0, err } @@ -77,7 +77,7 @@ func (i *ExternalIDP) CurrentSequence(event *models.Event) (uint64, error) { } func (i *ExternalIDP) EventQuery() (*models.SearchQuery, error) { - sequence, err := i.view.GetLatestExternalIDPSequence("") + sequence, err := i.view.GetLatestExternalIDPSequence() if err != nil { return nil, err } diff --git a/internal/auth/repository/eventsourcing/handler/user_grant.go b/internal/auth/repository/eventsourcing/handler/user_grant.go index 4244d0ac34..cc1fd98b16 100644 --- a/internal/auth/repository/eventsourcing/handler/user_grant.go +++ b/internal/auth/repository/eventsourcing/handler/user_grant.go @@ -83,8 +83,8 @@ func (_ *UserGrant) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{grant_es_model.UserGrantAggregate, iam_es_model.IAMAggregate, org_es_model.OrgAggregate, usr_es_model.UserAggregate, proj_es_model.ProjectAggregate} } -func (u *UserGrant) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := u.view.GetLatestUserGrantSequence(string(event.AggregateType)) +func (u *UserGrant) CurrentSequence() (uint64, error) { + sequence, err := u.view.GetLatestUserGrantSequence() if err != nil { return 0, err } @@ -98,7 +98,7 @@ func (u *UserGrant) EventQuery() (*models.SearchQuery, error) { return nil, err } } - sequence, err := u.view.GetLatestUserGrantSequence("") + sequence, err := u.view.GetLatestUserGrantSequence() if err != nil { return nil, err } diff --git a/internal/auth/repository/eventsourcing/handler/user_membership.go b/internal/auth/repository/eventsourcing/handler/user_membership.go index e1a41eccf5..ef76e28955 100644 --- a/internal/auth/repository/eventsourcing/handler/user_membership.go +++ b/internal/auth/repository/eventsourcing/handler/user_membership.go @@ -64,8 +64,8 @@ func (_ *UserMembership) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{iam_es_model.IAMAggregate, org_es_model.OrgAggregate, proj_es_model.ProjectAggregate, model.UserAggregate} } -func (m *UserMembership) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := m.view.GetLatestUserMembershipSequence(string(event.AggregateType)) +func (m *UserMembership) CurrentSequence() (uint64, error) { + sequence, err := m.view.GetLatestUserMembershipSequence() if err != nil { return 0, err } @@ -73,7 +73,7 @@ func (m *UserMembership) CurrentSequence(event *models.Event) (uint64, error) { } func (m *UserMembership) EventQuery() (*models.SearchQuery, error) { - sequence, err := m.view.GetLatestUserMembershipSequence("") + sequence, err := m.view.GetLatestUserMembershipSequence() if err != nil { return nil, err } diff --git a/internal/auth/repository/eventsourcing/handler/user_session.go b/internal/auth/repository/eventsourcing/handler/user_session.go index 7ef182f6ae..ac099cf4bd 100644 --- a/internal/auth/repository/eventsourcing/handler/user_session.go +++ b/internal/auth/repository/eventsourcing/handler/user_session.go @@ -55,8 +55,8 @@ func (_ *UserSession) AggregateTypes() []models.AggregateType { return []models.AggregateType{es_model.UserAggregate} } -func (u *UserSession) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := u.view.GetLatestUserSessionSequence(string(event.AggregateType)) +func (u *UserSession) CurrentSequence() (uint64, error) { + sequence, err := u.view.GetLatestUserSessionSequence() if err != nil { return 0, err } @@ -64,7 +64,7 @@ func (u *UserSession) CurrentSequence(event *models.Event) (uint64, error) { } func (u *UserSession) EventQuery() (*models.SearchQuery, error) { - sequence, err := u.view.GetLatestUserSessionSequence("") + sequence, err := u.view.GetLatestUserSessionSequence() if err != nil { return nil, err } diff --git a/internal/auth/repository/eventsourcing/view/application.go b/internal/auth/repository/eventsourcing/view/application.go index 5a7f2c6f1b..e0e6315dfb 100644 --- a/internal/auth/repository/eventsourcing/view/application.go +++ b/internal/auth/repository/eventsourcing/view/application.go @@ -57,7 +57,7 @@ func (v *View) DeleteApplicationsByProjectID(projectID string) error { } func (v *View) GetLatestApplicationSequence() (*repository.CurrentSequence, error) { - return v.latestSequence(applicationTable, "") + return v.latestSequence(applicationTable) } func (v *View) ProcessedApplicationSequence(event *models.Event) error { diff --git a/internal/auth/repository/eventsourcing/view/external_idps.go b/internal/auth/repository/eventsourcing/view/external_idps.go index 2928421cdc..05734c7d88 100644 --- a/internal/auth/repository/eventsourcing/view/external_idps.go +++ b/internal/auth/repository/eventsourcing/view/external_idps.go @@ -65,8 +65,8 @@ func (v *View) DeleteExternalIDPsByUserID(userID string, event *models.Event) er return v.ProcessedExternalIDPSequence(event) } -func (v *View) GetLatestExternalIDPSequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(externalIDPTable, aggregateType) +func (v *View) GetLatestExternalIDPSequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(externalIDPTable) } func (v *View) ProcessedExternalIDPSequence(event *models.Event) error { diff --git a/internal/auth/repository/eventsourcing/view/idp_configs.go b/internal/auth/repository/eventsourcing/view/idp_configs.go index 65a932b2d1..6a7b8a3910 100644 --- a/internal/auth/repository/eventsourcing/view/idp_configs.go +++ b/internal/auth/repository/eventsourcing/view/idp_configs.go @@ -41,8 +41,8 @@ func (v *View) DeleteIDPConfig(idpID string, event *models.Event) error { return v.ProcessedIDPConfigSequence(event) } -func (v *View) GetLatestIDPConfigSequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(idpConfigTable, aggregateType) +func (v *View) GetLatestIDPConfigSequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(idpConfigTable) } func (v *View) ProcessedIDPConfigSequence(event *models.Event) error { diff --git a/internal/auth/repository/eventsourcing/view/idp_providers.go b/internal/auth/repository/eventsourcing/view/idp_providers.go index afd25c15f8..2b17531533 100644 --- a/internal/auth/repository/eventsourcing/view/idp_providers.go +++ b/internal/auth/repository/eventsourcing/view/idp_providers.go @@ -61,8 +61,8 @@ func (v *View) DeleteIDPProvidersByAggregateID(aggregateID string, event *models return v.ProcessedIDPProviderSequence(event) } -func (v *View) GetLatestIDPProviderSequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(idpProviderTable, aggregateType) +func (v *View) GetLatestIDPProviderSequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(idpProviderTable) } func (v *View) ProcessedIDPProviderSequence(event *models.Event) error { diff --git a/internal/auth/repository/eventsourcing/view/key.go b/internal/auth/repository/eventsourcing/view/key.go index f8fca89445..574ff84337 100644 --- a/internal/auth/repository/eventsourcing/view/key.go +++ b/internal/auth/repository/eventsourcing/view/key.go @@ -57,8 +57,8 @@ func (v *View) DeleteKeyPair(keyID string, event *models.Event) error { return v.ProcessedKeySequence(event) } -func (v *View) GetLatestKeySequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(keyTable, aggregateType) +func (v *View) GetLatestKeySequence() (*repository.CurrentSequence, error) { + return v.latestSequence(keyTable) } func (v *View) ProcessedKeySequence(event *models.Event) error { diff --git a/internal/auth/repository/eventsourcing/view/login_policies.go b/internal/auth/repository/eventsourcing/view/login_policies.go index 2687cd8b6d..73bf483582 100644 --- a/internal/auth/repository/eventsourcing/view/login_policies.go +++ b/internal/auth/repository/eventsourcing/view/login_policies.go @@ -32,8 +32,8 @@ func (v *View) DeleteLoginPolicy(aggregateID string, event *models.Event) error return v.ProcessedLoginPolicySequence(event) } -func (v *View) GetLatestLoginPolicySequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(loginPolicyTable, aggregateType) +func (v *View) GetLatestLoginPolicySequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(loginPolicyTable) } func (v *View) ProcessedLoginPolicySequence(event *models.Event) error { diff --git a/internal/auth/repository/eventsourcing/view/machine_keys.go b/internal/auth/repository/eventsourcing/view/machine_keys.go index b5412d7240..908dc54d8c 100644 --- a/internal/auth/repository/eventsourcing/view/machine_keys.go +++ b/internal/auth/repository/eventsourcing/view/machine_keys.go @@ -53,8 +53,8 @@ func (v *View) DeleteMachineKeysByUserID(userID string, event *models.Event) err return v.ProcessedMachineKeySequence(event) } -func (v *View) GetLatestMachineKeySequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(machineKeyTable, aggregateType) +func (v *View) GetLatestMachineKeySequence() (*repository.CurrentSequence, error) { + return v.latestSequence(machineKeyTable) } func (v *View) ProcessedMachineKeySequence(event *models.Event) error { diff --git a/internal/auth/repository/eventsourcing/view/org.go b/internal/auth/repository/eventsourcing/view/org.go index 1b9a7c1b4c..e8407deb72 100644 --- a/internal/auth/repository/eventsourcing/view/org.go +++ b/internal/auth/repository/eventsourcing/view/org.go @@ -44,8 +44,8 @@ func (v *View) UpdateOrgSpoolerRunTimestamp() error { return v.updateSpoolerRunSequence(orgTable) } -func (v *View) GetLatestOrgSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(orgTable, aggregateType) +func (v *View) GetLatestOrgSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(orgTable) } func (v *View) ProcessedOrgSequence(event *models.Event) error { diff --git a/internal/auth/repository/eventsourcing/view/org_iam_policy.go b/internal/auth/repository/eventsourcing/view/org_iam_policy.go index a05592dae3..3dba05807d 100644 --- a/internal/auth/repository/eventsourcing/view/org_iam_policy.go +++ b/internal/auth/repository/eventsourcing/view/org_iam_policy.go @@ -32,8 +32,8 @@ func (v *View) DeleteOrgIAMPolicy(aggregateID string, event *models.Event) error return v.ProcessedOrgIAMPolicySequence(event) } -func (v *View) GetLatestOrgIAMPolicySequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(orgIAMPolicyTable, aggregateType) +func (v *View) GetLatestOrgIAMPolicySequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(orgIAMPolicyTable) } func (v *View) ProcessedOrgIAMPolicySequence(event *models.Event) error { diff --git a/internal/auth/repository/eventsourcing/view/password_complexity_policy.go b/internal/auth/repository/eventsourcing/view/password_complexity_policy.go index 43ce74f8c1..9c054fd8e5 100644 --- a/internal/auth/repository/eventsourcing/view/password_complexity_policy.go +++ b/internal/auth/repository/eventsourcing/view/password_complexity_policy.go @@ -32,8 +32,8 @@ func (v *View) DeletePasswordComplexityPolicy(aggregateID string, event *models. return v.ProcessedPasswordComplexityPolicySequence(event) } -func (v *View) GetLatestPasswordComplexityPolicySequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(passwordComplexityPolicyTable, aggregateType) +func (v *View) GetLatestPasswordComplexityPolicySequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(passwordComplexityPolicyTable) } func (v *View) ProcessedPasswordComplexityPolicySequence(event *models.Event) error { diff --git a/internal/auth/repository/eventsourcing/view/project_role.go b/internal/auth/repository/eventsourcing/view/project_role.go index c5a99bfe4a..a27672319c 100644 --- a/internal/auth/repository/eventsourcing/view/project_role.go +++ b/internal/auth/repository/eventsourcing/view/project_role.go @@ -53,8 +53,8 @@ func (v *View) DeleteProjectRolesByProjectID(projectID string) error { return view.DeleteProjectRolesByProjectID(v.Db, projectRoleTable, projectID) } -func (v *View) GetLatestProjectRoleSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(projectRoleTable, aggregateType) +func (v *View) GetLatestProjectRoleSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(projectRoleTable) } func (v *View) ProcessedProjectRoleSequence(event *models.Event) error { diff --git a/internal/auth/repository/eventsourcing/view/sequence.go b/internal/auth/repository/eventsourcing/view/sequence.go index d9eb6c7a64..cf75ab7606 100644 --- a/internal/auth/repository/eventsourcing/view/sequence.go +++ b/internal/auth/repository/eventsourcing/view/sequence.go @@ -12,15 +12,15 @@ const ( ) func (v *View) saveCurrentSequence(viewName string, event *models.Event) error { - return repository.SaveCurrentSequence(v.Db, sequencesTable, viewName, string(event.AggregateType), event.Sequence, event.CreationDate) + return repository.SaveCurrentSequence(v.Db, sequencesTable, viewName, event.Sequence, event.CreationDate) } -func (v *View) latestSequence(viewName, aggregateType string) (*repository.CurrentSequence, error) { - return repository.LatestSequence(v.Db, sequencesTable, viewName, aggregateType) +func (v *View) latestSequence(viewName string) (*repository.CurrentSequence, error) { + return repository.LatestSequence(v.Db, sequencesTable, viewName) } func (v *View) updateSpoolerRunSequence(viewName string) error { - currentSequence, err := repository.LatestSequence(v.Db, sequencesTable, viewName, "") + currentSequence, err := repository.LatestSequence(v.Db, sequencesTable, viewName) if err != nil { return err } diff --git a/internal/auth/repository/eventsourcing/view/token.go b/internal/auth/repository/eventsourcing/view/token.go index 105034a364..032953d529 100644 --- a/internal/auth/repository/eventsourcing/view/token.go +++ b/internal/auth/repository/eventsourcing/view/token.go @@ -68,8 +68,8 @@ func (v *View) DeleteApplicationTokens(event *models.Event, ids ...string) error return v.ProcessedTokenSequence(event) } -func (v *View) GetLatestTokenSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(tokenTable, aggregateType) +func (v *View) GetLatestTokenSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(tokenTable) } func (v *View) ProcessedTokenSequence(event *models.Event) error { diff --git a/internal/auth/repository/eventsourcing/view/user.go b/internal/auth/repository/eventsourcing/view/user.go index 21de8cef8d..a93a92c982 100644 --- a/internal/auth/repository/eventsourcing/view/user.go +++ b/internal/auth/repository/eventsourcing/view/user.go @@ -77,8 +77,8 @@ func (v *View) DeleteUser(userID string, event *models.Event) error { return v.ProcessedUserSequence(event) } -func (v *View) GetLatestUserSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(userTable, aggregateType) +func (v *View) GetLatestUserSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(userTable) } func (v *View) ProcessedUserSequence(event *models.Event) error { diff --git a/internal/auth/repository/eventsourcing/view/user_grant.go b/internal/auth/repository/eventsourcing/view/user_grant.go index d9a52a586e..4d713fd073 100644 --- a/internal/auth/repository/eventsourcing/view/user_grant.go +++ b/internal/auth/repository/eventsourcing/view/user_grant.go @@ -61,8 +61,8 @@ func (v *View) DeleteUserGrant(grantID string, event *models.Event) error { return v.ProcessedUserGrantSequence(event) } -func (v *View) GetLatestUserGrantSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(userGrantTable, aggregateType) +func (v *View) GetLatestUserGrantSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(userGrantTable) } func (v *View) ProcessedUserGrantSequence(event *models.Event) error { diff --git a/internal/auth/repository/eventsourcing/view/user_membership.go b/internal/auth/repository/eventsourcing/view/user_membership.go index f3d9fae70e..1574a668ef 100644 --- a/internal/auth/repository/eventsourcing/view/user_membership.go +++ b/internal/auth/repository/eventsourcing/view/user_membership.go @@ -77,8 +77,8 @@ func (v *View) DeleteUserMembershipsByAggregateIDAndObjectID(aggregateID, object return v.ProcessedUserMembershipSequence(event) } -func (v *View) GetLatestUserMembershipSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(userMembershipTable, aggregateType) +func (v *View) GetLatestUserMembershipSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(userMembershipTable) } func (v *View) ProcessedUserMembershipSequence(event *models.Event) error { diff --git a/internal/auth/repository/eventsourcing/view/user_session.go b/internal/auth/repository/eventsourcing/view/user_session.go index 16ce4c7986..01ec5360df 100644 --- a/internal/auth/repository/eventsourcing/view/user_session.go +++ b/internal/auth/repository/eventsourcing/view/user_session.go @@ -52,8 +52,8 @@ func (v *View) DeleteUserSessions(userID string, event *models.Event) error { return v.ProcessedUserSessionSequence(event) } -func (v *View) GetLatestUserSessionSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(userSessionTable, aggregateType) +func (v *View) GetLatestUserSessionSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(userSessionTable) } func (v *View) ProcessedUserSessionSequence(event *models.Event) error { diff --git a/internal/authz/repository/eventsourcing/handler/application.go b/internal/authz/repository/eventsourcing/handler/application.go index fcb84ee675..bb7bda0585 100644 --- a/internal/authz/repository/eventsourcing/handler/application.go +++ b/internal/authz/repository/eventsourcing/handler/application.go @@ -48,8 +48,8 @@ func (a *Application) AggregateTypes() []models.AggregateType { return []models.AggregateType{es_model.ProjectAggregate} } -func (a *Application) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := a.view.GetLatestApplicationSequence(string(event.AggregateType)) +func (a *Application) CurrentSequence() (uint64, error) { + sequence, err := a.view.GetLatestApplicationSequence() if err != nil { return 0, err } @@ -57,7 +57,7 @@ func (a *Application) CurrentSequence(event *models.Event) (uint64, error) { } func (a *Application) EventQuery() (*models.SearchQuery, error) { - sequence, err := a.view.GetLatestApplicationSequence("") + sequence, err := a.view.GetLatestApplicationSequence() if err != nil { return nil, err } diff --git a/internal/authz/repository/eventsourcing/handler/org.go b/internal/authz/repository/eventsourcing/handler/org.go index 34cc1a69e7..184316eec9 100644 --- a/internal/authz/repository/eventsourcing/handler/org.go +++ b/internal/authz/repository/eventsourcing/handler/org.go @@ -4,7 +4,6 @@ import ( "github.com/caos/logging" "github.com/caos/zitadel/internal/eventstore" - "github.com/caos/zitadel/internal/eventstore/models" es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/eventstore/query" "github.com/caos/zitadel/internal/eventstore/spooler" @@ -49,8 +48,8 @@ func (_ *Org) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{model.OrgAggregate} } -func (o *Org) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := o.view.GetLatestOrgSequence(string(event.AggregateType)) +func (o *Org) CurrentSequence() (uint64, error) { + sequence, err := o.view.GetLatestOrgSequence() if err != nil { return 0, err } @@ -58,7 +57,7 @@ func (o *Org) CurrentSequence(event *models.Event) (uint64, error) { } func (o *Org) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := o.view.GetLatestOrgSequence("") + sequence, err := o.view.GetLatestOrgSequence() if err != nil { return nil, err } diff --git a/internal/authz/repository/eventsourcing/handler/user_grant.go b/internal/authz/repository/eventsourcing/handler/user_grant.go index acdc5fde9e..78c894ea75 100644 --- a/internal/authz/repository/eventsourcing/handler/user_grant.go +++ b/internal/authz/repository/eventsourcing/handler/user_grant.go @@ -66,8 +66,8 @@ func (_ *UserGrant) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{iam_es_model.IAMAggregate, org_es_model.OrgAggregate, proj_es_model.ProjectAggregate} } -func (u *UserGrant) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := u.view.GetLatestUserGrantSequence(string(event.AggregateType)) +func (u *UserGrant) CurrentSequence() (uint64, error) { + sequence, err := u.view.GetLatestUserGrantSequence() if err != nil { return 0, err } @@ -81,7 +81,7 @@ func (u *UserGrant) EventQuery() (*models.SearchQuery, error) { return nil, err } } - sequence, err := u.view.GetLatestUserGrantSequence("") + sequence, err := u.view.GetLatestUserGrantSequence() if err != nil { return nil, err } diff --git a/internal/authz/repository/eventsourcing/view/application.go b/internal/authz/repository/eventsourcing/view/application.go index 84ae564981..9757a663fb 100644 --- a/internal/authz/repository/eventsourcing/view/application.go +++ b/internal/authz/repository/eventsourcing/view/application.go @@ -51,8 +51,8 @@ func (v *View) DeleteApplication(appID string, event *models.Event) error { return v.ProcessedApplicationSequence(event) } -func (v *View) GetLatestApplicationSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(applicationTable, aggregateType) +func (v *View) GetLatestApplicationSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(applicationTable) } func (v *View) ProcessedApplicationSequence(event *models.Event) error { diff --git a/internal/authz/repository/eventsourcing/view/org.go b/internal/authz/repository/eventsourcing/view/org.go index 6d27b5b071..aa99489968 100644 --- a/internal/authz/repository/eventsourcing/view/org.go +++ b/internal/authz/repository/eventsourcing/view/org.go @@ -36,8 +36,8 @@ func (v *View) ProcessedOrgFailedEvent(failedEvent *repository.FailedEvent) erro return v.saveFailedEvent(failedEvent) } -func (v *View) GetLatestOrgSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(orgTable, aggregateType) +func (v *View) GetLatestOrgSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(orgTable) } func (v *View) ProcessedOrgSequence(event *models.Event) error { diff --git a/internal/authz/repository/eventsourcing/view/sequence.go b/internal/authz/repository/eventsourcing/view/sequence.go index 42e6e20bfd..056c2a0399 100644 --- a/internal/authz/repository/eventsourcing/view/sequence.go +++ b/internal/authz/repository/eventsourcing/view/sequence.go @@ -12,15 +12,15 @@ const ( ) func (v *View) saveCurrentSequence(viewName string, event *models.Event) error { - return repository.SaveCurrentSequence(v.Db, sequencesTable, viewName, string(event.AggregateType), event.Sequence, event.CreationDate) + return repository.SaveCurrentSequence(v.Db, sequencesTable, viewName, event.Sequence, event.CreationDate) } -func (v *View) latestSequence(viewName, aggregateType string) (*repository.CurrentSequence, error) { - return repository.LatestSequence(v.Db, sequencesTable, viewName, aggregateType) +func (v *View) latestSequence(viewName string) (*repository.CurrentSequence, error) { + return repository.LatestSequence(v.Db, sequencesTable, viewName) } func (v *View) updateSpoolerRunSequence(viewName string) error { - currentSequence, err := repository.LatestSequence(v.Db, sequencesTable, viewName, "") + currentSequence, err := repository.LatestSequence(v.Db, sequencesTable, viewName) if err != nil { return err } diff --git a/internal/authz/repository/eventsourcing/view/token.go b/internal/authz/repository/eventsourcing/view/token.go index d2987a8194..8cd63fd8d1 100644 --- a/internal/authz/repository/eventsourcing/view/token.go +++ b/internal/authz/repository/eventsourcing/view/token.go @@ -40,8 +40,8 @@ func (v *View) DeleteSessionTokens(agentID, userID string, event *models.Event) return v.ProcessedTokenSequence(event) } -func (v *View) GetLatestTokenSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(tokenTable, aggregateType) +func (v *View) GetLatestTokenSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(tokenTable) } func (v *View) ProcessedTokenSequence(event *models.Event) error { diff --git a/internal/authz/repository/eventsourcing/view/user_grant.go b/internal/authz/repository/eventsourcing/view/user_grant.go index 84de9319ea..210d08dcb4 100644 --- a/internal/authz/repository/eventsourcing/view/user_grant.go +++ b/internal/authz/repository/eventsourcing/view/user_grant.go @@ -49,8 +49,8 @@ func (v *View) DeleteUserGrant(grantID string, event *models.Event) error { return v.ProcessedUserGrantSequence(event) } -func (v *View) GetLatestUserGrantSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(userGrantTable, aggregateType) +func (v *View) GetLatestUserGrantSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(userGrantTable) } func (v *View) ProcessedUserGrantSequence(event *models.Event) error { diff --git a/internal/eventstore/query/handler.go b/internal/eventstore/query/handler.go index 622a69156e..52ab1771be 100755 --- a/internal/eventstore/query/handler.go +++ b/internal/eventstore/query/handler.go @@ -5,6 +5,7 @@ import ( "time" "github.com/caos/logging" + "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/models" ) @@ -24,12 +25,12 @@ type Handler interface { QueryLimit() uint64 AggregateTypes() []models.AggregateType - CurrentSequence(*models.Event) (uint64, error) + CurrentSequence() (uint64, error) Eventstore() eventstore.Eventstore } func ReduceEvent(handler Handler, event *models.Event) { - currentSequence, err := handler.CurrentSequence(event) + currentSequence, err := handler.CurrentSequence() if err != nil { logging.Log("HANDL-BmpkC").WithError(err).Warn("unable to get current sequence") return @@ -46,32 +47,23 @@ func ReduceEvent(handler Handler, event *models.Event) { return } - processedSequences := map[models.AggregateType]uint64{} - for _, unprocessedEvent := range unprocessedEvents { - currentSequence, err := handler.CurrentSequence(unprocessedEvent) + currentSequence, err := handler.CurrentSequence() if err != nil { logging.Log("HANDL-BmpkC").WithError(err).Warn("unable to get current sequence") return } - _, ok := processedSequences[unprocessedEvent.AggregateType] - if !ok { - processedSequences[unprocessedEvent.AggregateType] = currentSequence - } - if processedSequences[unprocessedEvent.AggregateType] != currentSequence { - if currentSequence < processedSequences[unprocessedEvent.AggregateType] { - logging.LogWithFields("QUERY-DOYVN", - "processed", processedSequences[unprocessedEvent.AggregateType], - "current", currentSequence, - "view", handler.ViewModel()). - Warn("sequence not matching") - } + if unprocessedEvent.Sequence < currentSequence { + logging.LogWithFields("QUERY-DOYVN", + "unprocessed", unprocessedEvent.Sequence, + "current", currentSequence, + "view", handler.ViewModel()). + Warn("sequence not matching") return } err = handler.Reduce(unprocessedEvent) logging.LogWithFields("HANDL-V42TI", "seq", unprocessedEvent.Sequence).OnError(err).Warn("reduce failed") - processedSequences[unprocessedEvent.AggregateType] = unprocessedEvent.Sequence } if len(unprocessedEvents) == eventLimit { logging.LogWithFields("QUERY-BSqe9", "seq", event.Sequence).Warn("didnt process event") diff --git a/internal/eventstore/spooler/spooler_test.go b/internal/eventstore/spooler/spooler_test.go index 5b02977ea1..b685af2675 100644 --- a/internal/eventstore/spooler/spooler_test.go +++ b/internal/eventstore/spooler/spooler_test.go @@ -29,7 +29,7 @@ func (h *testHandler) AggregateTypes() []models.AggregateType { return nil } -func (h *testHandler) CurrentSequence(event *models.Event) (uint64, error) { +func (h *testHandler) CurrentSequence() (uint64, error) { return 0, nil } diff --git a/internal/iam/model/iam.go b/internal/iam/model/iam.go index ce88ed38c5..febe8f1422 100644 --- a/internal/iam/model/iam.go +++ b/internal/iam/model/iam.go @@ -17,6 +17,7 @@ const ( Step7 Step8 Step9 + Step10 //StepCount marks the the length of possible steps (StepCount-1 == last possible step) StepCount ) @@ -35,6 +36,8 @@ type IAM struct { DefaultPasswordComplexityPolicy *PasswordComplexityPolicy DefaultPasswordAgePolicy *PasswordAgePolicy DefaultPasswordLockoutPolicy *PasswordLockoutPolicy + DefaultMailTemplate *MailTemplate + DefaultMailTexts []*MailText } func (iam *IAM) GetMember(userID string) (int, *IAMMember) { @@ -54,3 +57,12 @@ func (iam *IAM) GetIDP(idpID string) (int, *IDPConfig) { } return -1, nil } + +func (iam *IAM) GetDefaultMailText(mailTextType string, language string) (int, *MailText) { + for i, m := range iam.DefaultMailTexts { + if m.MailTextType == mailTextType && m.Language == language { + return i, m + } + } + return -1, nil +} diff --git a/internal/iam/model/mail_template.go b/internal/iam/model/mail_template.go new file mode 100644 index 0000000000..8efeeff61b --- /dev/null +++ b/internal/iam/model/mail_template.go @@ -0,0 +1,17 @@ +package model + +import ( + "github.com/caos/zitadel/internal/eventstore/models" +) + +type MailTemplate struct { + models.ObjectRoot + + State PolicyState + Default bool + Template []byte +} + +func (p *MailTemplate) IsValid() bool { + return p.ObjectRoot.AggregateID != "" +} diff --git a/internal/iam/model/mail_template_view.go b/internal/iam/model/mail_template_view.go new file mode 100644 index 0000000000..40e04ce413 --- /dev/null +++ b/internal/iam/model/mail_template_view.go @@ -0,0 +1,47 @@ +package model + +import ( + "time" + + "github.com/caos/zitadel/internal/model" +) + +type MailTemplateView struct { + AggregateID string + Template []byte + Default bool + + CreationDate time.Time + ChangeDate time.Time + Sequence uint64 +} + +type MailTemplateSearchRequest struct { + Offset uint64 + Limit uint64 + SortingColumn MailTemplateSearchKey + Asc bool + Queries []*MailTemplateSearchQuery +} + +type MailTemplateSearchKey int32 + +const ( + MailTemplateSearchKeyUnspecified MailTemplateSearchKey = iota + MailTemplateSearchKeyAggregateID +) + +type MailTemplateSearchQuery struct { + Key MailTemplateSearchKey + Method model.SearchMethod + Value interface{} +} + +type MailTemplateSearchResponse struct { + Offset uint64 + Limit uint64 + TotalResult uint64 + Result []*MailTemplateView + Sequence uint64 + Timestamp time.Time +} diff --git a/internal/iam/model/mail_text.go b/internal/iam/model/mail_text.go new file mode 100644 index 0000000000..b0dd60b00a --- /dev/null +++ b/internal/iam/model/mail_text.go @@ -0,0 +1,28 @@ +package model + +import ( + "github.com/caos/zitadel/internal/eventstore/models" +) + +type MailTexts struct { + Texts []*MailText + Default bool +} +type MailText struct { + models.ObjectRoot + + State PolicyState + Default bool + MailTextType string + Language string + Title string + PreHeader string + Subject string + Greeting string + Text string + ButtonText string +} + +func (p *MailText) IsValid() bool { + return p.ObjectRoot.AggregateID != "" +} diff --git a/internal/iam/model/mail_text_view.go b/internal/iam/model/mail_text_view.go new file mode 100644 index 0000000000..425c58eca6 --- /dev/null +++ b/internal/iam/model/mail_text_view.go @@ -0,0 +1,60 @@ +package model + +import ( + "time" + + "github.com/caos/zitadel/internal/model" +) + +type MailTextsView struct { + Texts []*MailTextView + Default bool +} +type MailTextView struct { + AggregateID string + MailTextType string + Language string + Title string + PreHeader string + Subject string + Greeting string + Text string + ButtonText string + Default bool + + CreationDate time.Time + ChangeDate time.Time + Sequence uint64 +} + +type MailTextSearchRequest struct { + Offset uint64 + Limit uint64 + SortingColumn MailTextSearchKey + Asc bool + Queries []*MailTextSearchQuery +} + +type MailTextSearchKey int32 + +const ( + MailTextSearchKeyUnspecified MailTextSearchKey = iota + MailTextSearchKeyAggregateID + MailTextSearchKeyMailTextType + MailTextSearchKeyLanguage +) + +type MailTextSearchQuery struct { + Key MailTextSearchKey + Method model.SearchMethod + Value interface{} +} + +type MailTextSearchResponse struct { + Offset uint64 + Limit uint64 + TotalResult uint64 + Result []*MailTextView + Sequence uint64 + Timestamp time.Time +} diff --git a/internal/iam/repository/eventsourcing/eventstore.go b/internal/iam/repository/eventsourcing/eventstore.go index a484a5d573..4184336421 100644 --- a/internal/iam/repository/eventsourcing/eventstore.go +++ b/internal/iam/repository/eventsourcing/eventstore.go @@ -964,3 +964,118 @@ func (es *IAMEventstore) ChangeOrgIAMPolicy(ctx context.Context, policy *iam_mod es.iamCache.cacheIAM(repoIam) return model.OrgIAMPolicyToModel(repoIam.DefaultOrgIAMPolicy), nil } + +func (es *IAMEventstore) PrepareAddMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*model.IAM, *models.Aggregate, error) { + if template == nil || !template.IsValid() { + return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-j9l18", "Errors.IAM.MailTemplate.Empty") + } + iam, err := es.IAMByID(ctx, template.AggregateID) + if err != nil { + return nil, nil, err + } + + repoIam := model.IAMFromModel(iam) + mailTemplate := model.MailTemplateFromModel(template) + + addAggregate := MailTemplateAddedAggregate(es.Eventstore.AggregateCreator(), repoIam, mailTemplate) + aggregate, err := addAggregate(ctx) + if err != nil { + return nil, nil, err + } + return repoIam, aggregate, nil +} + +func (es *IAMEventstore) AddMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) { + repoIam, addAggregate, err := es.PrepareAddMailTemplate(ctx, template) + if err != nil { + return nil, err + } + err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) + if err != nil { + return nil, err + } + es.iamCache.cacheIAM(repoIam) + return model.MailTemplateToModel(repoIam.DefaultMailTemplate), nil +} + +func (es *IAMEventstore) ChangeMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) { + if template == nil || !template.IsValid() { + return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-gCnCs", "Errors.IAM.MailTemplateInvalid") + } + iam, err := es.IAMByID(ctx, template.AggregateID) + if err != nil { + return nil, err + } + + repoIam := model.IAMFromModel(iam) + repoMailTemplate := model.MailTemplateFromModel(template) + + addAggregate := MailTemplateChangedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoMailTemplate) + err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) + if err != nil { + return nil, err + } + es.iamCache.cacheIAM(repoIam) + return model.MailTemplateToModel(repoIam.DefaultMailTemplate), nil +} + +func (es *IAMEventstore) PrepareAddMailText(ctx context.Context, text *iam_model.MailText) (*model.IAM, *models.Aggregate, error) { + if text == nil || !text.IsValid() { + return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-j9l18", "Errors.IAM.MailText.Empty") + } + iam, err := es.IAMByID(ctx, text.AggregateID) + if err != nil { + return nil, nil, err + } + + repoIam := model.IAMFromModel(iam) + mailText := model.MailTextFromModel(text) + + addAggregate := MailTextAddedAggregate(es.Eventstore.AggregateCreator(), repoIam, mailText) + aggregate, err := addAggregate(ctx) + if err != nil { + return nil, nil, err + } + return repoIam, aggregate, nil +} + +func (es *IAMEventstore) AddMailText(ctx context.Context, text *iam_model.MailText) (*iam_model.MailText, error) { + repoIam, addAggregate, err := es.PrepareAddMailText(ctx, text) + if err != nil { + return nil, err + } + err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) + if err != nil { + return nil, err + } + es.iamCache.cacheIAM(repoIam) + + if _, m := model.GetMailText(repoIam.DefaultMailTexts, text.MailTextType, text.Language); m != nil { + return model.MailTextToModel(m), nil + } + return nil, caos_errs.ThrowInternal(nil, "EVENT-9AwUm", "Errors.Internal") +} + +func (es *IAMEventstore) ChangeMailText(ctx context.Context, text *iam_model.MailText) (*iam_model.MailText, error) { + if !text.IsValid() { + return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-J5xbB", "Errors.IAM.MailTextInvalid") + } + existing, err := es.IAMByID(ctx, text.AggregateID) + if err != nil { + return nil, err + } + if _, m := existing.GetDefaultMailText(text.MailTextType, text.Language); m == nil { + return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-0CTV3", "Errors.IAM.MailTextNotExisting") + } + repoIam := model.IAMFromModel(existing) + repoMember := model.MailTextFromModel(text) + + projectAggregate := MailTextChangedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoMember) + err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, projectAggregate) + es.iamCache.cacheIAM(repoIam) + + if _, m := model.GetMailText(repoIam.DefaultMailTexts, text.MailTextType, text.Language); m != nil { + return model.MailTextToModel(m), nil + } + return nil, caos_errs.ThrowInternal(nil, "EVENT-HawVx", "Errors.Internal") +} diff --git a/internal/iam/repository/eventsourcing/eventstore_mock_test.go b/internal/iam/repository/eventsourcing/eventstore_mock_test.go index e41a323014..18aff306bc 100644 --- a/internal/iam/repository/eventsourcing/eventstore_mock_test.go +++ b/internal/iam/repository/eventsourcing/eventstore_mock_test.go @@ -216,3 +216,29 @@ func GetMockManipulateIAMWithLabelPolicy(ctrl *gomock.Controller) *IAMEventstore mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) return GetMockedEventstore(ctrl, mockEs) } + +func GetMockManipulateIAMWithMailTemplate(ctrl *gomock.Controller) *IAMEventstore { + mailTemplate, _ := json.Marshal(model.MailTemplate{Template: []byte("")}) + events := []*es_models.Event{ + &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted}, + &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.MailTemplateAdded, Data: mailTemplate}, + } + mockEs := mock.NewMockEventstore(ctrl) + mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) + mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) + mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) + return GetMockedEventstore(ctrl, mockEs) +} + +func GetMockManipulateIAMWithMailText(ctrl *gomock.Controller) *IAMEventstore { + mailText, _ := json.Marshal(model.MailText{MailTextType: "Type", Language: "DE"}) + events := []*es_models.Event{ + &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted}, + &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.MailTextAdded, Data: mailText}, + } + mockEs := mock.NewMockEventstore(ctrl) + mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) + mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) + mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) + return GetMockedEventstore(ctrl, mockEs) +} diff --git a/internal/iam/repository/eventsourcing/eventstore_test.go b/internal/iam/repository/eventsourcing/eventstore_test.go index 5db2bfcc9a..3054044ac0 100644 --- a/internal/iam/repository/eventsourcing/eventstore_test.go +++ b/internal/iam/repository/eventsourcing/eventstore_test.go @@ -2816,3 +2816,321 @@ func TestChangeOrgIAMPolicy(t *testing.T) { }) } } +func TestAddMailTemplate(t *testing.T) { + ctrl := gomock.NewController(t) + type args struct { + es *IAMEventstore + ctx context.Context + policy *iam_model.MailTemplate + } + type res struct { + result *iam_model.MailTemplate + wantErr bool + errFunc func(err error) bool + } + tests := []struct { + name string + args args + res res + }{ + { + name: "add mailtemplate, ok", + args: args{ + es: GetMockManipulateIAM(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + policy: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + Template: []byte(""), + }, + }, + res: res{ + result: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + Template: []byte(""), + }, + }, + }, + { + name: "invalid policy", + args: args{ + es: GetMockManipulateIAM(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + policy: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + { + name: "existing iam not found", + args: args{ + es: GetMockManipulateIAMNotExisting(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + policy: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsNotFound, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := tt.args.es.AddMailTemplate(tt.args.ctx, tt.args.policy) + if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { + t.Errorf("got wrong err: %v ", err) + return + } + if tt.res.wantErr && tt.res.errFunc(err) { + return + } + if string(result.Template) != string(tt.res.result.Template) { + t.Errorf("got wrong result Template: expected: %v, actual: %v ", tt.res.result.Template, result.Template) + } + }) + } +} + +func TestChangeMailTemplate(t *testing.T) { + ctrl := gomock.NewController(t) + type args struct { + es *IAMEventstore + ctx context.Context + template *iam_model.MailTemplate + } + type res struct { + result *iam_model.MailTemplate + wantErr bool + errFunc func(err error) bool + } + tests := []struct { + name string + args args + res res + }{ + { + name: "add mail template, ok", + args: args{ + es: GetMockManipulateIAMWithMailTemplate(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + template: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + Template: []byte(""), + }, + }, + res: res{ + result: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + Template: []byte(""), + }, + }, + }, + { + name: "invalid mail template", + args: args{ + es: GetMockManipulateIAM(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + template: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + { + name: "existing iam not found", + args: args{ + es: GetMockManipulateIAMNotExisting(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + template: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsNotFound, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := tt.args.es.ChangeMailTemplate(tt.args.ctx, tt.args.template) + if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { + t.Errorf("got wrong err: %v ", err) + return + } + if tt.res.wantErr && tt.res.errFunc(err) { + return + } + if string(result.Template) != string(tt.res.result.Template) { + t.Errorf("got wrong result Template: expected: %v, actual: %v ", tt.res.result.Template, result.Template) + } + }) + } +} +func TestAddMailText(t *testing.T) { + ctrl := gomock.NewController(t) + type args struct { + es *IAMEventstore + ctx context.Context + policy *iam_model.MailText + } + type res struct { + result *iam_model.MailText + wantErr bool + errFunc func(err error) bool + } + tests := []struct { + name string + args args + res res + }{ + { + name: "add mailtemplate, ok", + args: args{ + es: GetMockManipulateIAM(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + policy: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + MailTextType: "Type", Language: "DE", + }, + }, + res: res{ + result: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + MailTextType: "Type", Language: "DE", + }, + }, + }, + { + name: "invalid policy", + args: args{ + es: GetMockManipulateIAM(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + policy: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + { + name: "existing iam not found", + args: args{ + es: GetMockManipulateIAMNotExisting(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + policy: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsNotFound, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := tt.args.es.AddMailText(tt.args.ctx, tt.args.policy) + if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { + t.Errorf("got wrong err: %v ", err) + return + } + if tt.res.wantErr && tt.res.errFunc(err) { + return + } + if string(result.MailTextType) != string(tt.res.result.MailTextType) { + t.Errorf("got wrong result MailTextType: expected: %v, actual: %v ", tt.res.result.MailTextType, result.MailTextType) + } + }) + } +} + +func TestChangeMailText(t *testing.T) { + ctrl := gomock.NewController(t) + type args struct { + es *IAMEventstore + ctx context.Context + policy *iam_model.MailText + } + type res struct { + result *iam_model.MailText + wantErr bool + errFunc func(err error) bool + } + tests := []struct { + name string + args args + res res + }{ + { + name: "change mailtemplate, ok", + args: args{ + es: GetMockManipulateIAMWithMailText(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + policy: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + MailTextType: "Type", Language: "DE", + }, + }, + res: res{ + result: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + MailTextType: "Type", Language: "DE", + }, + }, + }, + { + name: "invalid policy", + args: args{ + es: GetMockManipulateIAM(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + policy: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + { + name: "existing iam not found", + args: args{ + es: GetMockManipulateIAMNotExisting(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + policy: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsNotFound, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := tt.args.es.ChangeMailText(tt.args.ctx, tt.args.policy) + if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { + t.Errorf("got wrong err: %v ", err) + return + } + if tt.res.wantErr && tt.res.errFunc(err) { + return + } + if string(result.MailTextType) != string(tt.res.result.MailTextType) { + t.Errorf("got wrong result MailTextType: expected: %v, actual: %v ", tt.res.result.MailTextType, result.MailTextType) + } + }) + } +} diff --git a/internal/iam/repository/eventsourcing/iam.go b/internal/iam/repository/eventsourcing/iam.go index 0b5a128ca9..39803be9b5 100644 --- a/internal/iam/repository/eventsourcing/iam.go +++ b/internal/iam/repository/eventsourcing/iam.go @@ -232,6 +232,7 @@ func OIDCIDPConfigChangedAggregate(aggCreator *es_models.AggregateCreator, exist return agg.AppendEvent(model.OIDCIDPConfigChanged, changes) } } + func LabelPolicyAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.LabelPolicy) func(ctx context.Context) (*es_models.Aggregate, error) { return func(ctx context.Context) (*es_models.Aggregate, error) { if policy == nil { @@ -678,6 +679,101 @@ func checkExistingLoginPolicyIDPProviderValidation(idpConfigID string) func(...* } } +func MailTemplateAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, template *model.MailTemplate) func(ctx context.Context) (*es_models.Aggregate, error) { + return func(ctx context.Context) (*es_models.Aggregate, error) { + if template == nil { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-ZCfDS", "Errors.Internal") + } + agg, err := IAMAggregate(ctx, aggCreator, existing) + if err != nil { + return nil, err + } + validationQuery := es_models.NewSearchQuery(). + AggregateTypeFilter(model.IAMAggregate). + EventTypesFilter(model.MailTemplateAdded). + AggregateIDFilter(existing.AggregateID) + + validation := checkExistingMailTemplateValidation() + agg.SetPrecondition(validationQuery, validation) + return agg.AppendEvent(model.MailTemplateAdded, template) + } +} + +func checkExistingMailTemplateValidation() func(...*es_models.Event) error { + return func(events ...*es_models.Event) error { + for _, event := range events { + switch event.Type { + case model.MailTemplateAdded: + return errors.ThrowPreconditionFailed(nil, "EVENT-uKPiJ", "Errors.IAM.MailTemplate.AlreadyExists") + } + } + return nil + } +} + +func MailTemplateChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, template *model.MailTemplate) func(ctx context.Context) (*es_models.Aggregate, error) { + return func(ctx context.Context) (*es_models.Aggregate, error) { + if template == nil { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-s4PVD", "Errors.Internal") + } + agg, err := IAMAggregate(ctx, aggCreator, existing) + if err != nil { + return nil, err + } + changes := existing.DefaultMailTemplate.Changes(template) + if len(changes) == 0 { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-hxxSm", "Errors.NoChangesFound") + } + return agg.AppendEvent(model.MailTemplateChanged, changes) + } +} + +func MailTextAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, text *model.MailText) func(ctx context.Context) (*es_models.Aggregate, error) { + return func(ctx context.Context) (*es_models.Aggregate, error) { + if text == nil { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-ZCfDS", "Errors.Internal") + } + agg, err := IAMAggregate(ctx, aggCreator, existing) + if err != nil { + return nil, err + } + validationQuery := es_models.NewSearchQuery(). + AggregateTypeFilter(model.IAMAggregate). + EventTypesFilter(model.MailTextAdded). + AggregateIDFilter(existing.AggregateID) + + validation := checkExistingMailTextValidation() + agg.SetPrecondition(validationQuery, validation) + return agg.AppendEvent(model.MailTextAdded, text) + } +} + +func checkExistingMailTextValidation() func(...*es_models.Event) error { + return func(events ...*es_models.Event) error { + for _, event := range events { + switch event.Type { + case model.MailTextAdded: + return errors.ThrowPreconditionFailed(nil, "EVENT-ijzeq", "Errors.IAM.MailText.AlreadyExists") + } + } + return nil + } +} + +func MailTextChangedAggregate(aggCreator *es_models.AggregateCreator, existingIAM *model.IAM, text *model.MailText) func(ctx context.Context) (*es_models.Aggregate, error) { + return func(ctx context.Context) (*es_models.Aggregate, error) { + if text == nil { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-mgYpV", "Errors.Internal") + } + + agg, err := IAMAggregate(ctx, aggCreator, existingIAM) + if err != nil { + return nil, err + } + return agg.AppendEvent(model.MailTextChanged, text) + } +} + func checkExistingLoginPolicySecondFactorValidation(mfaType int32) func(...*es_models.Event) error { return func(events ...*es_models.Event) error { mfas := make([]int32, 0) diff --git a/internal/iam/repository/eventsourcing/model/iam.go b/internal/iam/repository/eventsourcing/model/iam.go index 464fa28f64..23478dfdbc 100644 --- a/internal/iam/repository/eventsourcing/model/iam.go +++ b/internal/iam/repository/eventsourcing/model/iam.go @@ -32,6 +32,8 @@ type IAM struct { IDPs []*IDPConfig `json:"-"` DefaultLoginPolicy *LoginPolicy `json:"-"` DefaultLabelPolicy *LabelPolicy `json:"-"` + DefaultMailTemplate *MailTemplate `json:"-"` + DefaultMailTexts []*MailText `json:"-"` DefaultOrgIAMPolicy *OrgIAMPolicy `json:"-"` DefaultPasswordComplexityPolicy *PasswordComplexityPolicy `json:"-"` DefaultPasswordAgePolicy *PasswordAgePolicy `json:"-"` @@ -41,14 +43,16 @@ type IAM struct { func IAMFromModel(iam *model.IAM) *IAM { members := IAMMembersFromModel(iam.Members) idps := IDPConfigsFromModel(iam.IDPs) + mailTexts := MailTextsFromModel(iam.DefaultMailTexts) converted := &IAM{ - ObjectRoot: iam.ObjectRoot, - SetUpStarted: Step(iam.SetUpStarted), - SetUpDone: Step(iam.SetUpDone), - GlobalOrgID: iam.GlobalOrgID, - IAMProjectID: iam.IAMProjectID, - Members: members, - IDPs: idps, + ObjectRoot: iam.ObjectRoot, + SetUpStarted: Step(iam.SetUpStarted), + SetUpDone: Step(iam.SetUpDone), + GlobalOrgID: iam.GlobalOrgID, + IAMProjectID: iam.IAMProjectID, + Members: members, + IDPs: idps, + DefaultMailTexts: mailTexts, } if iam.DefaultLoginPolicy != nil { converted.DefaultLoginPolicy = LoginPolicyFromModel(iam.DefaultLoginPolicy) @@ -56,6 +60,9 @@ func IAMFromModel(iam *model.IAM) *IAM { if iam.DefaultLabelPolicy != nil { converted.DefaultLabelPolicy = LabelPolicyFromModel(iam.DefaultLabelPolicy) } + if iam.DefaultMailTemplate != nil { + converted.DefaultMailTemplate = MailTemplateFromModel(iam.DefaultMailTemplate) + } if iam.DefaultPasswordComplexityPolicy != nil { converted.DefaultPasswordComplexityPolicy = PasswordComplexityPolicyFromModel(iam.DefaultPasswordComplexityPolicy) } @@ -74,6 +81,7 @@ func IAMFromModel(iam *model.IAM) *IAM { func IAMToModel(iam *IAM) *model.IAM { members := IAMMembersToModel(iam.Members) idps := IDPConfigsToModel(iam.IDPs) + mailTexts := MailTextsToModel(iam.DefaultMailTexts) converted := &model.IAM{ ObjectRoot: iam.ObjectRoot, SetUpStarted: domain.Step(iam.SetUpStarted), @@ -82,6 +90,7 @@ func IAMToModel(iam *IAM) *model.IAM { IAMProjectID: iam.IAMProjectID, Members: members, IDPs: idps, + DefaultMailTexts: mailTexts, } if iam.DefaultLoginPolicy != nil { converted.DefaultLoginPolicy = LoginPolicyToModel(iam.DefaultLoginPolicy) @@ -89,6 +98,9 @@ func IAMToModel(iam *IAM) *model.IAM { if iam.DefaultLabelPolicy != nil { converted.DefaultLabelPolicy = LabelPolicyToModel(iam.DefaultLabelPolicy) } + if iam.DefaultMailTemplate != nil { + converted.DefaultMailTemplate = MailTemplateToModel(iam.DefaultMailTemplate) + } if iam.DefaultPasswordComplexityPolicy != nil { converted.DefaultPasswordComplexityPolicy = PasswordComplexityPolicyToModel(iam.DefaultPasswordComplexityPolicy) } @@ -181,6 +193,14 @@ func (i *IAM) AppendEvent(event *es_models.Event) (err error) { return i.appendAddLabelPolicyEvent(event) case LabelPolicyChanged: return i.appendChangeLabelPolicyEvent(event) + case MailTemplateAdded: + return i.appendAddMailTemplateEvent(event) + case MailTemplateChanged: + return i.appendChangeMailTemplateEvent(event) + case MailTextAdded: + return i.appendAddMailTextEvent(event) + case MailTextChanged: + return i.appendChangeMailTextEvent(event) case PasswordComplexityPolicyAdded: return i.appendAddPasswordComplexityPolicyEvent(event) case PasswordComplexityPolicyChanged: diff --git a/internal/iam/repository/eventsourcing/model/mail_template.go b/internal/iam/repository/eventsourcing/model/mail_template.go new file mode 100644 index 0000000000..b328089abd --- /dev/null +++ b/internal/iam/repository/eventsourcing/model/mail_template.go @@ -0,0 +1,64 @@ +package model + +import ( + b64 "encoding/base64" + "encoding/json" + + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/models" + es_models "github.com/caos/zitadel/internal/eventstore/models" + iam_model "github.com/caos/zitadel/internal/iam/model" +) + +type MailTemplate struct { + models.ObjectRoot + State int32 `json:"-"` + Template []byte +} + +func MailTemplateToModel(template *MailTemplate) *iam_model.MailTemplate { + return &iam_model.MailTemplate{ + ObjectRoot: template.ObjectRoot, + State: iam_model.PolicyState(template.State), + Template: template.Template, + } +} + +func MailTemplateFromModel(template *iam_model.MailTemplate) *MailTemplate { + return &MailTemplate{ + ObjectRoot: template.ObjectRoot, + State: int32(template.State), + Template: template.Template, + } +} + +func (p *MailTemplate) Changes(changed *MailTemplate) map[string]interface{} { + changes := make(map[string]interface{}, 1) + if b64.StdEncoding.EncodeToString(changed.Template) != b64.StdEncoding.EncodeToString(p.Template) { + changes["template"] = b64.StdEncoding.EncodeToString(changed.Template) + } + + return changes +} + +func (i *IAM) appendAddMailTemplateEvent(event *es_models.Event) error { + i.DefaultMailTemplate = new(MailTemplate) + err := i.DefaultMailTemplate.SetDataLabel(event) + if err != nil { + return err + } + i.DefaultMailTemplate.ObjectRoot.CreationDate = event.CreationDate + return nil +} + +func (i *IAM) appendChangeMailTemplateEvent(event *es_models.Event) error { + return i.DefaultMailTemplate.SetDataLabel(event) +} + +func (p *MailTemplate) SetDataLabel(event *es_models.Event) error { + err := json.Unmarshal(event.Data, p) + if err != nil { + return errors.ThrowInternal(err, "MODEL-ikjhf", "unable to unmarshal data") + } + return nil +} diff --git a/internal/iam/repository/eventsourcing/model/mail_template_test.go b/internal/iam/repository/eventsourcing/model/mail_template_test.go new file mode 100644 index 0000000000..279a059865 --- /dev/null +++ b/internal/iam/repository/eventsourcing/model/mail_template_test.go @@ -0,0 +1,126 @@ +package model + +import ( + "encoding/json" + "testing" + + es_models "github.com/caos/zitadel/internal/eventstore/models" +) + +func TestMailTemplateChanges(t *testing.T) { + type args struct { + existing *MailTemplate + new *MailTemplate + } + type res struct { + changesLen int + } + tests := []struct { + name string + args args + res res + }{ + { + name: "mailtemplate all attributes change", + args: args{ + existing: &MailTemplate{Template: []byte("")}, + new: &MailTemplate{Template: []byte("")}, + }, + res: res{ + changesLen: 1, + }, + }, + { + name: "no changes", + args: args{ + existing: &MailTemplate{Template: []byte("")}, + new: &MailTemplate{Template: []byte("")}, + }, + res: res{ + changesLen: 0, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + changes := tt.args.existing.Changes(tt.args.new) + if len(changes) != tt.res.changesLen { + t.Errorf("got wrong changes len: expected: %v, actual: %v ", tt.res.changesLen, len(changes)) + } + }) + } +} + +func TestAppendAddMailTemplateEvent(t *testing.T) { + type args struct { + iam *IAM + policy *MailTemplate + event *es_models.Event + } + tests := []struct { + name string + args args + result *IAM + }{ + { + name: "append add label policy event", + args: args{ + iam: new(IAM), + policy: &MailTemplate{Template: []byte("")}, + event: new(es_models.Event), + }, + result: &IAM{DefaultMailTemplate: &MailTemplate{Template: []byte("")}}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.args.policy != nil { + data, _ := json.Marshal(tt.args.policy) + tt.args.event.Data = data + } + tt.args.iam.appendAddMailTemplateEvent(tt.args.event) + if string(tt.result.DefaultMailTemplate.Template) != string(tt.args.iam.DefaultMailTemplate.Template) { + t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultMailTemplate.Template, tt.args.iam.DefaultMailTemplate.Template) + } + }) + } +} + +func TestAppendChangeMailTemplateEvent(t *testing.T) { + type args struct { + iam *IAM + policy *MailTemplate + event *es_models.Event + } + tests := []struct { + name string + args args + result *IAM + }{ + { + name: "append change label policy event", + args: args{ + iam: &IAM{DefaultMailTemplate: &MailTemplate{ + Template: []byte(""), + }}, + policy: &MailTemplate{Template: []byte("")}, + event: &es_models.Event{}, + }, + result: &IAM{DefaultMailTemplate: &MailTemplate{ + Template: []byte(""), + }}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.args.policy != nil { + data, _ := json.Marshal(tt.args.policy) + tt.args.event.Data = data + } + tt.args.iam.appendChangeMailTemplateEvent(tt.args.event) + if string(tt.result.DefaultMailTemplate.Template) != string(tt.args.iam.DefaultMailTemplate.Template) { + t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultMailTemplate.Template, tt.args.iam.DefaultMailTemplate.Template) + } + }) + } +} diff --git a/internal/iam/repository/eventsourcing/model/mail_text.go b/internal/iam/repository/eventsourcing/model/mail_text.go new file mode 100644 index 0000000000..912be7a7a0 --- /dev/null +++ b/internal/iam/repository/eventsourcing/model/mail_text.go @@ -0,0 +1,157 @@ +package model + +import ( + "encoding/json" + + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/models" + es_models "github.com/caos/zitadel/internal/eventstore/models" + iam_model "github.com/caos/zitadel/internal/iam/model" +) + +type MailText struct { + models.ObjectRoot + State int32 `json:"-"` + MailTextType string + Language string + Title string + PreHeader string + Subject string + Greeting string + Text string + ButtonText string +} + +func GetMailText(mailTexts []*MailText, mailTextType string, language string) (int, *MailText) { + for i, m := range mailTexts { + if m.MailTextType == mailTextType && m.Language == language { + return i, m + } + } + return -1, nil +} + +func MailTextsToModel(mailTexts []*MailText) []*iam_model.MailText { + convertedMailTexts := make([]*iam_model.MailText, len(mailTexts)) + for i, m := range mailTexts { + convertedMailTexts[i] = MailTextToModel(m) + } + return convertedMailTexts +} + +func MailTextToModel(mailText *MailText) *iam_model.MailText { + return &iam_model.MailText{ + ObjectRoot: mailText.ObjectRoot, + State: iam_model.PolicyState(mailText.State), + MailTextType: mailText.MailTextType, + Language: mailText.Language, + Title: mailText.Title, + PreHeader: mailText.PreHeader, + Subject: mailText.Subject, + Greeting: mailText.Greeting, + Text: mailText.Text, + ButtonText: mailText.ButtonText, + } +} + +func MailTextsFromModel(mailTexts []*iam_model.MailText) []*MailText { + convertedMailTexts := make([]*MailText, len(mailTexts)) + for i, m := range mailTexts { + convertedMailTexts[i] = MailTextFromModel(m) + } + return convertedMailTexts +} + +func MailTextFromModel(mailText *iam_model.MailText) *MailText { + return &MailText{ + ObjectRoot: mailText.ObjectRoot, + State: int32(mailText.State), + MailTextType: mailText.MailTextType, + Language: mailText.Language, + Title: mailText.Title, + PreHeader: mailText.PreHeader, + Subject: mailText.Subject, + Greeting: mailText.Greeting, + Text: mailText.Text, + ButtonText: mailText.ButtonText, + } +} + +func (p *MailText) Changes(changed *MailText) map[string]interface{} { + changes := make(map[string]interface{}, 8) + + changes["mailTextType"] = changed.MailTextType + + changes["language"] = changed.Language + + if changed.Title != p.Title { + changes["title"] = changed.Title + } + + if changed.PreHeader != p.PreHeader { + changes["preHeader"] = changed.PreHeader + } + + if changed.Subject != p.Subject { + changes["subject"] = changed.Subject + } + + if changed.Greeting != p.Greeting { + changes["greeting"] = changed.Greeting + } + + if changed.Text != p.Text { + changes["text"] = changed.Text + } + + if changed.ButtonText != p.ButtonText { + changes["buttonText"] = changed.ButtonText + } + + return changes +} + +func (i *IAM) appendAddMailTextEvent(event *es_models.Event) error { + mailText := &MailText{} + err := mailText.SetDataLabel(event) + if err != nil { + return err + } + mailText.ObjectRoot.CreationDate = event.CreationDate + i.DefaultMailTexts = append(i.DefaultMailTexts, mailText) + return nil +} + +func (i *IAM) appendChangeMailTextEvent(event *es_models.Event) error { + mailText := &MailText{} + err := mailText.SetDataLabel(event) + if err != nil { + return err + } + if n, m := GetMailText(i.DefaultMailTexts, mailText.MailTextType, mailText.Language); m != nil { + i.DefaultMailTexts[n] = mailText + } + return nil +} + +func (i *IAM) appendRemoveMailTextEvent(event *es_models.Event) error { + mailText := &MailText{} + err := mailText.SetDataLabel(event) + if err != nil { + return err + } + if n, m := GetMailText(i.DefaultMailTexts, mailText.MailTextType, mailText.Language); m != nil { + i.DefaultMailTexts[n] = i.DefaultMailTexts[len(i.DefaultMailTexts)-1] + i.DefaultMailTexts[len(i.DefaultMailTexts)-1] = nil + i.DefaultMailTexts = i.DefaultMailTexts[:len(i.DefaultMailTexts)-1] + } + return nil +} + +func (p *MailText) SetDataLabel(event *es_models.Event) error { + err := json.Unmarshal(event.Data, p) + if err != nil { + return errors.ThrowInternal(err, "MODEL-3FUV5", "unable to unmarshal data") + } + return nil +} diff --git a/internal/iam/repository/eventsourcing/model/mail_text_test.go b/internal/iam/repository/eventsourcing/model/mail_text_test.go new file mode 100644 index 0000000000..84f5d1189e --- /dev/null +++ b/internal/iam/repository/eventsourcing/model/mail_text_test.go @@ -0,0 +1,134 @@ +package model + +import ( + "encoding/json" + "testing" + + es_models "github.com/caos/zitadel/internal/eventstore/models" +) + +func TestAppendAddMailTextEvent(t *testing.T) { + type args struct { + iam *IAM + mailText *MailText + event *es_models.Event + } + tests := []struct { + name string + args args + result *IAM + }{ + { + name: "append add mailText event", + args: args{ + iam: &IAM{}, + mailText: &MailText{ + MailTextType: "PasswordReset", + Language: "DE"}, + event: &es_models.Event{}, + }, + result: &IAM{DefaultMailTexts: []*MailText{&MailText{ + MailTextType: "PasswordReset", + Language: "DE"}}}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.args.mailText != nil { + data, _ := json.Marshal(tt.args.mailText) + tt.args.event.Data = data + } + tt.args.iam.appendAddMailTextEvent(tt.args.event) + if len(tt.args.iam.DefaultMailTexts) != 1 { + t.Errorf("got wrong result should have one mailText actual: %v ", len(tt.args.iam.DefaultMailTexts)) + } + if tt.args.iam.DefaultMailTexts[0] == tt.result.DefaultMailTexts[0] { + t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultMailTexts[0], tt.args.iam.DefaultMailTexts[0]) + } + }) + } +} + +func TestAppendChangeMailTextEvent(t *testing.T) { + type args struct { + iam *IAM + mailText *MailText + event *es_models.Event + } + tests := []struct { + name string + args args + result *IAM + }{ + { + name: "append change mailText event", + args: args{ + iam: &IAM{DefaultMailTexts: []*MailText{&MailText{ + MailTextType: "PasswordReset", + Language: "DE"}}}, + mailText: &MailText{ + MailTextType: "ChangedPasswordReset", + Language: "DE"}, + event: &es_models.Event{}, + }, + result: &IAM{DefaultMailTexts: []*MailText{&MailText{ + MailTextType: "PasswordReset", + Language: "ChangedDE"}}}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.args.mailText != nil { + data, _ := json.Marshal(tt.args.mailText) + tt.args.event.Data = data + } + tt.args.iam.appendChangeMailTextEvent(tt.args.event) + if len(tt.args.iam.DefaultMailTexts) != 1 { + t.Errorf("got wrong result should have one mailText actual: %v ", len(tt.args.iam.DefaultMailTexts)) + } + if tt.args.iam.DefaultMailTexts[0] == tt.result.DefaultMailTexts[0] { + t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultMailTexts[0], tt.args.iam.DefaultMailTexts[0]) + } + }) + } +} + +func TestAppendRemoveMailTextEvent(t *testing.T) { + type args struct { + iam *IAM + mailText *MailText + event *es_models.Event + } + tests := []struct { + name string + args args + result *IAM + }{ + { + name: "append remove mailText event", + args: args{ + iam: &IAM{DefaultMailTexts: []*MailText{&MailText{ + MailTextType: "PasswordReset", + Language: "DE", + Subject: "Subject"}}}, + mailText: &MailText{ + MailTextType: "PasswordReset", + Language: "DE"}, + event: &es_models.Event{}, + }, + result: &IAM{DefaultMailTexts: []*MailText{}}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.args.mailText != nil { + data, _ := json.Marshal(tt.args.mailText) + tt.args.event.Data = data + } + tt.args.iam.appendRemoveMailTextEvent(tt.args.event) + if len(tt.args.iam.DefaultMailTexts) != 0 { + t.Errorf("got wrong result should have no mailText actual: %v ", len(tt.args.iam.DefaultMailTexts)) + } + }) + } +} diff --git a/internal/iam/repository/eventsourcing/model/types.go b/internal/iam/repository/eventsourcing/model/types.go index fa2b1eb643..c558db062c 100644 --- a/internal/iam/repository/eventsourcing/model/types.go +++ b/internal/iam/repository/eventsourcing/model/types.go @@ -38,6 +38,11 @@ const ( LabelPolicyAdded models.EventType = "iam.policy.label.added" LabelPolicyChanged models.EventType = "iam.policy.label.changed" + MailTemplateAdded models.EventType = "iam.mail.template.added" + MailTemplateChanged models.EventType = "iam.mail.template.changed" + MailTextAdded models.EventType = "iam.mail.text.added" + MailTextChanged models.EventType = "iam.mail.text.changed" + PasswordComplexityPolicyAdded models.EventType = "iam.policy.password.complexity.added" PasswordComplexityPolicyChanged models.EventType = "iam.policy.password.complexity.changed" diff --git a/internal/iam/repository/view/idp_view.go b/internal/iam/repository/view/idp_view.go index 44fcd93edf..d6505a2180 100644 --- a/internal/iam/repository/view/idp_view.go +++ b/internal/iam/repository/view/idp_view.go @@ -11,8 +11,8 @@ import ( func IDPByID(db *gorm.DB, table, idpID string) (*model.IDPConfigView, error) { idp := new(model.IDPConfigView) - userIDQuery := &model.IDPConfigSearchQuery{Key: iam_model.IDPConfigSearchKeyIdpConfigID, Value: idpID, Method: global_model.SearchMethodEquals} - query := repository.PrepareGetByQuery(table, userIDQuery) + idpIDQuery := &model.IDPConfigSearchQuery{Key: iam_model.IDPConfigSearchKeyIdpConfigID, Value: idpID, Method: global_model.SearchMethodEquals} + query := repository.PrepareGetByQuery(table, idpIDQuery) err := query(db, idp) if caos_errs.IsNotFound(err) { return nil, caos_errs.ThrowNotFound(nil, "VIEW-Ahq2s", "Errors.IAM.IdpNotExisting") diff --git a/internal/iam/repository/view/label_policy_view.go b/internal/iam/repository/view/label_policy_view.go index e77f3b1dc9..b294f44d42 100644 --- a/internal/iam/repository/view/label_policy_view.go +++ b/internal/iam/repository/view/label_policy_view.go @@ -11,8 +11,8 @@ import ( func GetLabelPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.LabelPolicyView, error) { policy := new(model.LabelPolicyView) - userIDQuery := &model.LabelPolicySearchQuery{Key: iam_model.LabelPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals} - query := repository.PrepareGetByQuery(table, userIDQuery) + aggregateIDQuery := &model.LabelPolicySearchQuery{Key: iam_model.LabelPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals} + query := repository.PrepareGetByQuery(table, aggregateIDQuery) err := query(db, policy) if caos_errs.IsNotFound(err) { return nil, caos_errs.ThrowNotFound(nil, "VIEW-68G11", "Errors.IAM.LabelPolicy.NotExisting") diff --git a/internal/iam/repository/view/login_policy_view.go b/internal/iam/repository/view/login_policy_view.go index cbcd3beacf..dbcb30afea 100644 --- a/internal/iam/repository/view/login_policy_view.go +++ b/internal/iam/repository/view/login_policy_view.go @@ -11,8 +11,8 @@ import ( func GetLoginPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.LoginPolicyView, error) { policy := new(model.LoginPolicyView) - userIDQuery := &model.LoginPolicySearchQuery{Key: iam_model.LoginPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals} - query := repository.PrepareGetByQuery(table, userIDQuery) + aggregateIDQuery := &model.LoginPolicySearchQuery{Key: iam_model.LoginPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals} + query := repository.PrepareGetByQuery(table, aggregateIDQuery) err := query(db, policy) if caos_errs.IsNotFound(err) { return nil, caos_errs.ThrowNotFound(nil, "VIEW-Lso0cs", "Errors.IAM.LoginPolicy.NotExisting") diff --git a/internal/iam/repository/view/mail_template_view.go b/internal/iam/repository/view/mail_template_view.go new file mode 100644 index 0000000000..dab453cb3b --- /dev/null +++ b/internal/iam/repository/view/mail_template_view.go @@ -0,0 +1,32 @@ +package view + +import ( + caos_errs "github.com/caos/zitadel/internal/errors" + iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/iam/repository/view/model" + global_model "github.com/caos/zitadel/internal/model" + "github.com/caos/zitadel/internal/view/repository" + "github.com/jinzhu/gorm" +) + +func GetMailTemplateByAggregateID(db *gorm.DB, table, aggregateID string) (*model.MailTemplateView, error) { + template := new(model.MailTemplateView) + aggregateIDQuery := &model.MailTemplateSearchQuery{Key: iam_model.MailTemplateSearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals} + query := repository.PrepareGetByQuery(table, aggregateIDQuery) + err := query(db, template) + if caos_errs.IsNotFound(err) { + return nil, caos_errs.ThrowNotFound(nil, "VIEW-iPnmU", "Errors.IAM.MailTemplate.NotExisting") + } + return template, err +} + +func PutMailTemplate(db *gorm.DB, table string, template *model.MailTemplateView) error { + save := repository.PrepareSave(table) + return save(db, template) +} + +func DeleteMailTemplate(db *gorm.DB, table, aggregateID string) error { + delete := repository.PrepareDeleteByKey(table, model.MailTemplateSearchKey(iam_model.MailTemplateSearchKeyAggregateID), aggregateID) + + return delete(db) +} diff --git a/internal/iam/repository/view/mail_text_view.go b/internal/iam/repository/view/mail_text_view.go new file mode 100644 index 0000000000..31f440293a --- /dev/null +++ b/internal/iam/repository/view/mail_text_view.go @@ -0,0 +1,54 @@ +package view + +import ( + caos_errs "github.com/caos/zitadel/internal/errors" + iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/iam/repository/view/model" + global_model "github.com/caos/zitadel/internal/model" + "github.com/caos/zitadel/internal/view/repository" + "github.com/jinzhu/gorm" + "strings" +) + +func GetMailTexts(db *gorm.DB, table string, aggregateID string) ([]*model.MailTextView, error) { + texts := make([]*model.MailTextView, 0) + queries := []*iam_model.MailTextSearchQuery{ + { + Key: iam_model.MailTextSearchKeyAggregateID, + Value: aggregateID, + Method: global_model.SearchMethodEquals, + }, + } + query := repository.PrepareSearchQuery(table, model.MailTextSearchRequest{Queries: queries}) + _, err := query(db, &texts) + if err != nil { + return nil, err + } + return texts, nil +} + +func GetMailTextByIDs(db *gorm.DB, table, aggregateID string, textType string, language string) (*model.MailTextView, error) { + mailText := new(model.MailTextView) + aggregateIDQuery := &model.MailTextSearchQuery{Key: iam_model.MailTextSearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals} + textTypeQuery := &model.MailTextSearchQuery{Key: iam_model.MailTextSearchKeyMailTextType, Value: textType, Method: global_model.SearchMethodEquals} + languageQuery := &model.MailTextSearchQuery{Key: iam_model.MailTextSearchKeyLanguage, Value: strings.ToUpper(language), Method: global_model.SearchMethodEquals} + query := repository.PrepareGetByQuery(table, aggregateIDQuery, textTypeQuery, languageQuery) + err := query(db, mailText) + if caos_errs.IsNotFound(err) { + return nil, caos_errs.ThrowNotFound(nil, "VIEW-IiJjm", "Errors.IAM.MailText.NotExisting") + } + return mailText, err +} + +func PutMailText(db *gorm.DB, table string, mailText *model.MailTextView) error { + save := repository.PrepareSave(table) + return save(db, mailText) +} + +func DeleteMailText(db *gorm.DB, table, aggregateID string, textType string, language string) error { + aggregateIDSearch := repository.Key{Key: model.MailTextSearchKey(iam_model.MailTextSearchKeyAggregateID), Value: aggregateID} + textTypeSearch := repository.Key{Key: model.MailTextSearchKey(iam_model.MailTextSearchKeyMailTextType), Value: textType} + languageSearch := repository.Key{Key: model.MailTextSearchKey(iam_model.MailTextSearchKeyLanguage), Value: language} + delete := repository.PrepareDeleteByKeys(table, aggregateIDSearch, textTypeSearch, languageSearch) + return delete(db) +} diff --git a/internal/iam/repository/view/model/mail_template.go b/internal/iam/repository/view/model/mail_template.go new file mode 100644 index 0000000000..29ab111d43 --- /dev/null +++ b/internal/iam/repository/view/model/mail_template.go @@ -0,0 +1,80 @@ +package model + +import ( + "encoding/json" + "time" + + org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" + + es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" + + "github.com/caos/logging" + caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/iam/model" +) + +const ( + MailTemplateKeyAggregateID = "aggregate_id" +) + +type MailTemplateView struct { + AggregateID string `json:"-" gorm:"column:aggregate_id;primary_key"` + CreationDate time.Time `json:"-" gorm:"column:creation_date"` + ChangeDate time.Time `json:"-" gorm:"column:change_date"` + State int32 `json:"-" gorm:"column:mail_template_state"` + + Template []byte `json:"template" gorm:"column:template"` + Default bool `json:"-" gorm:"-"` + + Sequence uint64 `json:"-" gorm:"column:sequence"` +} + +func MailTemplateViewFromModel(template *model.MailTemplateView) *MailTemplateView { + return &MailTemplateView{ + AggregateID: template.AggregateID, + Sequence: template.Sequence, + CreationDate: template.CreationDate, + ChangeDate: template.ChangeDate, + Template: template.Template, + Default: template.Default, + } +} + +func MailTemplateViewToModel(template *MailTemplateView) *model.MailTemplateView { + return &model.MailTemplateView{ + AggregateID: template.AggregateID, + Sequence: template.Sequence, + CreationDate: template.CreationDate, + ChangeDate: template.ChangeDate, + Template: template.Template, + Default: template.Default, + } +} + +func (i *MailTemplateView) AppendEvent(event *models.Event) (err error) { + i.Sequence = event.Sequence + i.ChangeDate = event.CreationDate + switch event.Type { + case es_model.MailTemplateAdded, org_es_model.MailTemplateAdded: + i.setRootData(event) + i.CreationDate = event.CreationDate + err = i.SetData(event) + case es_model.MailTemplateChanged, org_es_model.MailTemplateChanged: + i.ChangeDate = event.CreationDate + err = i.SetData(event) + } + return err +} + +func (r *MailTemplateView) setRootData(event *models.Event) { + r.AggregateID = event.AggregateID +} + +func (r *MailTemplateView) SetData(event *models.Event) error { + if err := json.Unmarshal(event.Data, r); err != nil { + logging.Log("MODEL-YDZmZ").WithError(err).Error("could not unmarshal event data") + return caos_errs.ThrowInternal(err, "MODEL-sKWwO", "Could not unmarshal data") + } + return nil +} diff --git a/internal/iam/repository/view/model/mail_template_query.go b/internal/iam/repository/view/model/mail_template_query.go new file mode 100644 index 0000000000..60eb11049e --- /dev/null +++ b/internal/iam/repository/view/model/mail_template_query.go @@ -0,0 +1,59 @@ +package model + +import ( + iam_model "github.com/caos/zitadel/internal/iam/model" + global_model "github.com/caos/zitadel/internal/model" + "github.com/caos/zitadel/internal/view/repository" +) + +type MailTemplateSearchRequest iam_model.MailTemplateSearchRequest +type MailTemplateSearchQuery iam_model.MailTemplateSearchQuery +type MailTemplateSearchKey iam_model.MailTemplateSearchKey + +func (req MailTemplateSearchRequest) GetLimit() uint64 { + return req.Limit +} + +func (req MailTemplateSearchRequest) GetOffset() uint64 { + return req.Offset +} + +func (req MailTemplateSearchRequest) GetSortingColumn() repository.ColumnKey { + if req.SortingColumn == iam_model.MailTemplateSearchKeyUnspecified { + return nil + } + return MailTemplateSearchKey(req.SortingColumn) +} + +func (req MailTemplateSearchRequest) GetAsc() bool { + return req.Asc +} + +func (req MailTemplateSearchRequest) GetQueries() []repository.SearchQuery { + result := make([]repository.SearchQuery, len(req.Queries)) + for i, q := range req.Queries { + result[i] = MailTemplateSearchQuery{Key: q.Key, Value: q.Value, Method: q.Method} + } + return result +} + +func (req MailTemplateSearchQuery) GetKey() repository.ColumnKey { + return MailTemplateSearchKey(req.Key) +} + +func (req MailTemplateSearchQuery) GetMethod() global_model.SearchMethod { + return req.Method +} + +func (req MailTemplateSearchQuery) GetValue() interface{} { + return req.Value +} + +func (key MailTemplateSearchKey) ToColumnName() string { + switch iam_model.MailTemplateSearchKey(key) { + case iam_model.MailTemplateSearchKeyAggregateID: + return MailTemplateKeyAggregateID + default: + return "" + } +} diff --git a/internal/iam/repository/view/model/mail_text.go b/internal/iam/repository/view/model/mail_text.go new file mode 100644 index 0000000000..959f9d3fce --- /dev/null +++ b/internal/iam/repository/view/model/mail_text.go @@ -0,0 +1,117 @@ +package model + +import ( + "encoding/json" + "time" + + org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" + + es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" + + "github.com/caos/logging" + caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/iam/model" +) + +const ( + MailTextKeyAggregateID = "aggregate_id" + MailTextKeyMailTextType = "mail_text_type" + MailTextKeyLanguage = "language" +) + +type MailTextView struct { + AggregateID string `json:"-" gorm:"column:aggregate_id;primary_key"` + CreationDate time.Time `json:"-" gorm:"column:creation_date"` + ChangeDate time.Time `json:"-" gorm:"column:change_date"` + State int32 `json:"-" gorm:"column:mail_text_state"` + + MailTextType string `json:"mailTextType" gorm:"column:mail_text_type;primary_key"` + Language string `json:"language" gorm:"column:language;primary_key"` + Title string `json:"title" gorm:"column:title"` + PreHeader string `json:"preHeader" gorm:"column:pre_header"` + Subject string `json:"subject" gorm:"column:subject"` + Greeting string `json:"greeting" gorm:"column:greeting"` + Text string `json:"text" gorm:"column:text"` + ButtonText string `json:"buttonText" gorm:"column:button_text"` + Default bool `json:"-" gorm:"-"` + + Sequence uint64 `json:"-" gorm:"column:sequence"` +} + +func MailTextViewFromModel(template *model.MailTextView) *MailTextView { + return &MailTextView{ + AggregateID: template.AggregateID, + Sequence: template.Sequence, + CreationDate: template.CreationDate, + ChangeDate: template.ChangeDate, + MailTextType: template.MailTextType, + Language: template.Language, + Title: template.Title, + PreHeader: template.PreHeader, + Subject: template.Subject, + Greeting: template.Greeting, + Text: template.Text, + ButtonText: template.ButtonText, + Default: template.Default, + } +} + +func MailTextsViewToModel(textsIn []*MailTextView, defaultIn bool) *model.MailTextsView { + return &model.MailTextsView{ + Texts: mailTextsViewToModelArr(textsIn, defaultIn), + } +} + +func mailTextsViewToModelArr(texts []*MailTextView, defaultIn bool) []*model.MailTextView { + result := make([]*model.MailTextView, len(texts)) + for i, r := range texts { + r.Default = defaultIn + result[i] = MailTextViewToModel(r) + } + return result +} + +func MailTextViewToModel(template *MailTextView) *model.MailTextView { + return &model.MailTextView{ + AggregateID: template.AggregateID, + Sequence: template.Sequence, + CreationDate: template.CreationDate, + ChangeDate: template.ChangeDate, + MailTextType: template.MailTextType, + Language: template.Language, + Title: template.Title, + PreHeader: template.PreHeader, + Subject: template.Subject, + Greeting: template.Greeting, + Text: template.Text, + ButtonText: template.ButtonText, + Default: template.Default, + } +} + +func (i *MailTextView) AppendEvent(event *models.Event) (err error) { + i.Sequence = event.Sequence + switch event.Type { + case es_model.MailTextAdded, org_es_model.MailTextAdded: + i.setRootData(event) + i.CreationDate = event.CreationDate + err = i.SetData(event) + case es_model.MailTextChanged, org_es_model.MailTextChanged: + i.ChangeDate = event.CreationDate + err = i.SetData(event) + } + return err +} + +func (r *MailTextView) setRootData(event *models.Event) { + r.AggregateID = event.AggregateID +} + +func (r *MailTextView) SetData(event *models.Event) error { + if err := json.Unmarshal(event.Data, r); err != nil { + logging.Log("MODEL-UFqAG").WithError(err).Error("could not unmarshal event data") + return caos_errs.ThrowInternal(err, "MODEL-5CVaR", "Could not unmarshal data") + } + return nil +} diff --git a/internal/iam/repository/view/model/mail_text_query.go b/internal/iam/repository/view/model/mail_text_query.go new file mode 100644 index 0000000000..ed1d1a24aa --- /dev/null +++ b/internal/iam/repository/view/model/mail_text_query.go @@ -0,0 +1,63 @@ +package model + +import ( + iam_model "github.com/caos/zitadel/internal/iam/model" + global_model "github.com/caos/zitadel/internal/model" + "github.com/caos/zitadel/internal/view/repository" +) + +type MailTextSearchRequest iam_model.MailTextSearchRequest +type MailTextSearchQuery iam_model.MailTextSearchQuery +type MailTextSearchKey iam_model.MailTextSearchKey + +func (req MailTextSearchRequest) GetLimit() uint64 { + return req.Limit +} + +func (req MailTextSearchRequest) GetOffset() uint64 { + return req.Offset +} + +func (req MailTextSearchRequest) GetSortingColumn() repository.ColumnKey { + if req.SortingColumn == iam_model.MailTextSearchKeyUnspecified { + return nil + } + return MailTextSearchKey(req.SortingColumn) +} + +func (req MailTextSearchRequest) GetAsc() bool { + return req.Asc +} + +func (req MailTextSearchRequest) GetQueries() []repository.SearchQuery { + result := make([]repository.SearchQuery, len(req.Queries)) + for i, q := range req.Queries { + result[i] = MailTextSearchQuery{Key: q.Key, Value: q.Value, Method: q.Method} + } + return result +} + +func (req MailTextSearchQuery) GetKey() repository.ColumnKey { + return MailTextSearchKey(req.Key) +} + +func (req MailTextSearchQuery) GetMethod() global_model.SearchMethod { + return req.Method +} + +func (req MailTextSearchQuery) GetValue() interface{} { + return req.Value +} + +func (key MailTextSearchKey) ToColumnName() string { + switch iam_model.MailTextSearchKey(key) { + case iam_model.MailTextSearchKeyAggregateID: + return MailTextKeyAggregateID + case iam_model.MailTextSearchKeyMailTextType: + return MailTextKeyMailTextType + case iam_model.MailTextSearchKeyLanguage: + return MailTextKeyLanguage + default: + return "" + } +} diff --git a/internal/iam/repository/view/org_iam_policy_view.go b/internal/iam/repository/view/org_iam_policy_view.go index 322697ec2f..574081bc40 100644 --- a/internal/iam/repository/view/org_iam_policy_view.go +++ b/internal/iam/repository/view/org_iam_policy_view.go @@ -11,8 +11,8 @@ import ( func GetOrgIAMPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.OrgIAMPolicyView, error) { policy := new(model.OrgIAMPolicyView) - userIDQuery := &model.OrgIAMPolicySearchQuery{Key: iam_model.OrgIAMPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals} - query := repository.PrepareGetByQuery(table, userIDQuery) + aggregateIDQuery := &model.OrgIAMPolicySearchQuery{Key: iam_model.OrgIAMPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals} + query := repository.PrepareGetByQuery(table, aggregateIDQuery) err := query(db, policy) if caos_errs.IsNotFound(err) { return nil, caos_errs.ThrowNotFound(nil, "VIEW-5fi9s", "Errors.IAM.OrgIAMPolicy.NotExisting") diff --git a/internal/iam/repository/view/password_age_policy_view.go b/internal/iam/repository/view/password_age_policy_view.go index 1fbd8c0ca1..eb85938edc 100644 --- a/internal/iam/repository/view/password_age_policy_view.go +++ b/internal/iam/repository/view/password_age_policy_view.go @@ -11,8 +11,8 @@ import ( func GetPasswordAgePolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.PasswordAgePolicyView, error) { policy := new(model.PasswordAgePolicyView) - userIDQuery := &model.PasswordAgePolicySearchQuery{Key: iam_model.PasswordAgePolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals} - query := repository.PrepareGetByQuery(table, userIDQuery) + aggregateIDQuery := &model.PasswordAgePolicySearchQuery{Key: iam_model.PasswordAgePolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals} + query := repository.PrepareGetByQuery(table, aggregateIDQuery) err := query(db, policy) if caos_errs.IsNotFound(err) { return nil, caos_errs.ThrowNotFound(nil, "VIEW-Lso0cs", "Errors.IAM.PasswordAgePolicy.NotExisting") diff --git a/internal/iam/repository/view/password_complexity_policy_view.go b/internal/iam/repository/view/password_complexity_policy_view.go index 938c73ff75..75713cead9 100644 --- a/internal/iam/repository/view/password_complexity_policy_view.go +++ b/internal/iam/repository/view/password_complexity_policy_view.go @@ -11,8 +11,8 @@ import ( func GetPasswordComplexityPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.PasswordComplexityPolicyView, error) { policy := new(model.PasswordComplexityPolicyView) - userIDQuery := &model.PasswordComplexityPolicySearchQuery{Key: iam_model.PasswordComplexityPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals} - query := repository.PrepareGetByQuery(table, userIDQuery) + aggregateIDQuery := &model.PasswordComplexityPolicySearchQuery{Key: iam_model.PasswordComplexityPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals} + query := repository.PrepareGetByQuery(table, aggregateIDQuery) err := query(db, policy) if caos_errs.IsNotFound(err) { return nil, caos_errs.ThrowNotFound(nil, "VIEW-Lso0cs", "Errors.IAM.PasswordComplexityPolicy.NotExisting") diff --git a/internal/iam/repository/view/password_lockout_policy_view.go b/internal/iam/repository/view/password_lockout_policy_view.go index 74f95204c8..e5bdc9922e 100644 --- a/internal/iam/repository/view/password_lockout_policy_view.go +++ b/internal/iam/repository/view/password_lockout_policy_view.go @@ -11,8 +11,8 @@ import ( func GetPasswordLockoutPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.PasswordLockoutPolicyView, error) { policy := new(model.PasswordLockoutPolicyView) - userIDQuery := &model.PasswordLockoutPolicySearchQuery{Key: iam_model.PasswordLockoutPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals} - query := repository.PrepareGetByQuery(table, userIDQuery) + aggregateIDQuery := &model.PasswordLockoutPolicySearchQuery{Key: iam_model.PasswordLockoutPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals} + query := repository.PrepareGetByQuery(table, aggregateIDQuery) err := query(db, policy) if caos_errs.IsNotFound(err) { return nil, caos_errs.ThrowNotFound(nil, "VIEW-Lso0cs", "Errors.IAM.PasswordLockoutPolicy.NotExisting") diff --git a/internal/management/repository/eventsourcing/eventstore/org.go b/internal/management/repository/eventsourcing/eventstore/org.go index 4cd80676aa..c236e55358 100644 --- a/internal/management/repository/eventsourcing/eventstore/org.go +++ b/internal/management/repository/eventsourcing/eventstore/org.go @@ -108,7 +108,7 @@ func (repo *OrgRepository) GetMyOrgIamPolicy(ctx context.Context) (*iam_model.Or func (repo *OrgRepository) SearchMyOrgDomains(ctx context.Context, request *org_model.OrgDomainSearchRequest) (*org_model.OrgDomainSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) request.Queries = append(request.Queries, &org_model.OrgDomainSearchQuery{Key: org_model.OrgDomainSearchKeyOrgID, Method: global_model.SearchMethodEquals, Value: authz.GetCtxData(ctx).OrgID}) - sequence, sequenceErr := repo.View.GetLatestOrgDomainSequence("") + sequence, sequenceErr := repo.View.GetLatestOrgDomainSequence() logging.Log("EVENT-SLowp").OnError(sequenceErr).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Warn("could not read latest org domain sequence") domains, count, err := repo.View.SearchOrgDomains(request) if err != nil { @@ -205,7 +205,7 @@ func (repo *OrgRepository) RemoveMyOrgMember(ctx context.Context, userID string) func (repo *OrgRepository) SearchMyOrgMembers(ctx context.Context, request *org_model.OrgMemberSearchRequest) (*org_model.OrgMemberSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) request.Queries[len(request.Queries)-1] = &org_model.OrgMemberSearchQuery{Key: org_model.OrgMemberSearchKeyOrgID, Method: global_model.SearchMethodEquals, Value: authz.GetCtxData(ctx).OrgID} - sequence, sequenceErr := repo.View.GetLatestOrgMemberSequence("") + sequence, sequenceErr := repo.View.GetLatestOrgMemberSequence() logging.Log("EVENT-Smu3d").OnError(sequenceErr).Warn("could not read latest org member sequence") members, count, err := repo.View.SearchOrgMembers(request) if err != nil { @@ -292,7 +292,7 @@ func (repo *OrgRepository) SearchIDPConfigs(ctx context.Context, request *iam_mo request.EnsureLimit(repo.SearchLimit) request.AppendMyOrgQuery(authz.GetCtxData(ctx).OrgID, repo.SystemDefaults.IamID) - sequence, sequenceErr := repo.View.GetLatestIDPConfigSequence("") + sequence, sequenceErr := repo.View.GetLatestIDPConfigSequence() logging.Log("EVENT-Dk8si").OnError(sequenceErr).Warn("could not read latest idp config sequence") idps, count, err := repo.View.SearchIDPConfigs(request) if err != nil { @@ -414,7 +414,7 @@ func (repo *OrgRepository) SearchIDPProviders(ctx context.Context, request *iam_ request.AppendAggregateIDQuery(authz.GetCtxData(ctx).OrgID) } request.EnsureLimit(repo.SearchLimit) - sequence, sequenceErr := repo.View.GetLatestIDPProviderSequence("") + sequence, sequenceErr := repo.View.GetLatestIDPProviderSequence() logging.Log("EVENT-Tuiks").OnError(sequenceErr).Warn("could not read latest iam sequence") providers, count, err := repo.View.SearchIDPProviders(request) if err != nil { @@ -703,3 +703,83 @@ func (repo *OrgRepository) RemovePasswordLockoutPolicy(ctx context.Context) erro }} return repo.OrgEventstore.RemovePasswordLockoutPolicy(ctx, policy) } + +func (repo *OrgRepository) GetDefaultMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error) { + template, err := repo.View.MailTemplateByAggregateID(repo.SystemDefaults.IamID) + if err != nil { + return nil, err + } + template.Default = true + return iam_es_model.MailTemplateViewToModel(template), err +} + +func (repo *OrgRepository) GetMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error) { + template, err := repo.View.MailTemplateByAggregateID(authz.GetCtxData(ctx).OrgID) + if errors.IsNotFound(err) { + template, err = repo.View.MailTemplateByAggregateID(repo.SystemDefaults.IamID) + if err != nil { + return nil, err + } + template.Default = true + } + if err != nil { + return nil, err + } + return iam_es_model.MailTemplateViewToModel(template), err +} + +func (repo *OrgRepository) AddMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) { + template.AggregateID = authz.GetCtxData(ctx).OrgID + return repo.OrgEventstore.AddMailTemplate(ctx, template) +} + +func (repo *OrgRepository) ChangeMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) { + template.AggregateID = authz.GetCtxData(ctx).OrgID + return repo.OrgEventstore.ChangeMailTemplate(ctx, template) +} + +func (repo *OrgRepository) RemoveMailTemplate(ctx context.Context) error { + template := &iam_model.MailTemplate{ObjectRoot: models.ObjectRoot{ + AggregateID: authz.GetCtxData(ctx).OrgID, + }} + return repo.OrgEventstore.RemoveMailTemplate(ctx, template) +} + +func (repo *OrgRepository) GetDefaultMailTexts(ctx context.Context) (*iam_model.MailTextsView, error) { + texts, err := repo.View.MailTextsByAggregateID(repo.SystemDefaults.IamID) + if err != nil { + return nil, err + } + return iam_es_model.MailTextsViewToModel(texts, true), err +} + +func (repo *OrgRepository) GetMailTexts(ctx context.Context) (*iam_model.MailTextsView, error) { + defaultIn := false + texts, err := repo.View.MailTextsByAggregateID(authz.GetCtxData(ctx).OrgID) + if errors.IsNotFound(err) || len(texts) == 0 { + texts, err = repo.View.MailTextsByAggregateID(repo.SystemDefaults.IamID) + if err != nil { + return nil, err + } + defaultIn = true + } + if err != nil { + return nil, err + } + return iam_es_model.MailTextsViewToModel(texts, defaultIn), err +} + +func (repo *OrgRepository) AddMailText(ctx context.Context, text *iam_model.MailText) (*iam_model.MailText, error) { + text.AggregateID = authz.GetCtxData(ctx).OrgID + return repo.OrgEventstore.AddMailText(ctx, text) +} + +func (repo *OrgRepository) ChangeMailText(ctx context.Context, text *iam_model.MailText) (*iam_model.MailText, error) { + text.AggregateID = authz.GetCtxData(ctx).OrgID + return repo.OrgEventstore.ChangeMailText(ctx, text) +} + +func (repo *OrgRepository) RemoveMailText(ctx context.Context, text *iam_model.MailText) error { + text.AggregateID = authz.GetCtxData(ctx).OrgID + return repo.OrgEventstore.RemoveMailText(ctx, text) +} diff --git a/internal/management/repository/eventsourcing/eventstore/project.go b/internal/management/repository/eventsourcing/eventstore/project.go index 25c980366d..a014a8e7ec 100644 --- a/internal/management/repository/eventsourcing/eventstore/project.go +++ b/internal/management/repository/eventsourcing/eventstore/project.go @@ -65,7 +65,7 @@ func (repo *ProjectRepo) ProjectByID(ctx context.Context, id string) (*proj_mode func (repo *ProjectRepo) SearchProjects(ctx context.Context, request *proj_model.ProjectViewSearchRequest) (*proj_model.ProjectViewSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) - sequence, sequenceErr := repo.View.GetLatestProjectSequence("") + sequence, sequenceErr := repo.View.GetLatestProjectSequence() logging.Log("EVENT-Edc56").OnError(sequenceErr).Warn("could not read latest project sequence") permissions := authz.GetRequestPermissionsFromCtx(ctx) @@ -132,7 +132,7 @@ func (repo *ProjectRepo) ProjectMemberByID(ctx context.Context, projectID, userI func (repo *ProjectRepo) SearchProjectMembers(ctx context.Context, request *proj_model.ProjectMemberSearchRequest) (*proj_model.ProjectMemberSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) - sequence, sequenceErr := repo.View.GetLatestProjectMemberSequence("") + sequence, sequenceErr := repo.View.GetLatestProjectMemberSequence() logging.Log("EVENT-3dgt6").OnError(sequenceErr).Warn("could not read latest project member sequence") members, count, err := repo.View.SearchProjectMembers(request) if err != nil { @@ -154,7 +154,7 @@ func (repo *ProjectRepo) SearchProjectMembers(ctx context.Context, request *proj func (repo *ProjectRepo) SearchProjectRoles(ctx context.Context, projectID string, request *proj_model.ProjectRoleSearchRequest) (*proj_model.ProjectRoleSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) request.AppendProjectQuery(projectID) - sequence, sequenceErr := repo.View.GetLatestProjectRoleSequence("") + sequence, sequenceErr := repo.View.GetLatestProjectRoleSequence() logging.Log("LSp0d-47suf").OnError(sequenceErr).Warn("could not read latest project role sequence") roles, count, err := repo.View.SearchProjectRoles(request) if err != nil { @@ -229,7 +229,7 @@ func (repo *ProjectRepo) ApplicationByID(ctx context.Context, projectID, appID s func (repo *ProjectRepo) SearchApplications(ctx context.Context, request *proj_model.ApplicationSearchRequest) (*proj_model.ApplicationSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) - sequence, sequenceErr := repo.View.GetLatestApplicationSequence("") + sequence, sequenceErr := repo.View.GetLatestApplicationSequence() logging.Log("EVENT-SKe8s").OnError(sequenceErr).Warn("could not read latest application sequence") apps, count, err := repo.View.SearchApplications(request) if err != nil { @@ -282,7 +282,7 @@ func (repo *ProjectRepo) ProjectGrantByID(ctx context.Context, grantID string) ( func (repo *ProjectRepo) SearchProjectGrants(ctx context.Context, request *proj_model.ProjectGrantViewSearchRequest) (*proj_model.ProjectGrantViewSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) - sequence, sequenceErr := repo.View.GetLatestProjectGrantSequence("") + sequence, sequenceErr := repo.View.GetLatestProjectGrantSequence() logging.Log("EVENT-Skw9f").OnError(sequenceErr).Warn("could not read latest project grant sequence") projects, count, err := repo.View.SearchProjectGrants(request) if err != nil { @@ -303,7 +303,7 @@ func (repo *ProjectRepo) SearchProjectGrants(ctx context.Context, request *proj_ func (repo *ProjectRepo) SearchGrantedProjects(ctx context.Context, request *proj_model.ProjectGrantViewSearchRequest) (*proj_model.ProjectGrantViewSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) - sequence, sequenceErr := repo.View.GetLatestProjectGrantSequence("") + sequence, sequenceErr := repo.View.GetLatestProjectGrantSequence() logging.Log("EVENT-Skw9f").OnError(sequenceErr).Warn("could not read latest project grant sequence") permissions := authz.GetRequestPermissionsFromCtx(ctx) @@ -362,7 +362,7 @@ func (repo *ProjectRepo) ProjectGrantMemberByID(ctx context.Context, projectID, func (repo *ProjectRepo) SearchProjectGrantMembers(ctx context.Context, request *proj_model.ProjectGrantMemberSearchRequest) (*proj_model.ProjectGrantMemberSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) - sequence, sequenceErr := repo.View.GetLatestProjectGrantMemberSequence("") + sequence, sequenceErr := repo.View.GetLatestProjectGrantMemberSequence() logging.Log("EVENT-Du8sk").OnError(sequenceErr).Warn("could not read latest project grant sequence") members, count, err := repo.View.SearchProjectGrantMembers(request) if err != nil { diff --git a/internal/management/repository/eventsourcing/eventstore/user.go b/internal/management/repository/eventsourcing/eventstore/user.go index b586d87504..9368470587 100644 --- a/internal/management/repository/eventsourcing/eventstore/user.go +++ b/internal/management/repository/eventsourcing/eventstore/user.go @@ -59,7 +59,7 @@ func (repo *UserRepo) UserByID(ctx context.Context, id string) (*usr_model.UserV func (repo *UserRepo) SearchUsers(ctx context.Context, request *usr_model.UserSearchRequest) (*usr_model.UserSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) - sequence, sequenceErr := repo.View.GetLatestUserSequence("") + sequence, sequenceErr := repo.View.GetLatestUserSequence() logging.Log("EVENT-Lcn7d").OnError(sequenceErr).Warn("could not read latest user sequence") users, count, err := repo.View.SearchUsers(request) if err != nil { @@ -145,7 +145,7 @@ func (repo *UserRepo) ProfileByID(ctx context.Context, userID string) (*usr_mode func (repo *UserRepo) SearchExternalIDPs(ctx context.Context, request *usr_model.ExternalIDPSearchRequest) (*usr_model.ExternalIDPSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) - sequence, seqErr := repo.View.GetLatestExternalIDPSequence("") + sequence, seqErr := repo.View.GetLatestExternalIDPSequence() logging.Log("EVENT-Qs7uf").OnError(seqErr).Warn("could not read latest external idp sequence") externalIDPS, count, err := repo.View.SearchExternalIDPs(request) if err != nil { @@ -174,7 +174,7 @@ func (repo *UserRepo) GetMachineKey(ctx context.Context, userID, keyID string) ( func (repo *UserRepo) SearchMachineKeys(ctx context.Context, request *usr_model.MachineKeySearchRequest) (*usr_model.MachineKeySearchResponse, error) { request.EnsureLimit(repo.SearchLimit) - sequence, seqErr := repo.View.GetLatestMachineKeySequence("") + sequence, seqErr := repo.View.GetLatestMachineKeySequence() logging.Log("EVENT-Sk8fs").OnError(seqErr).Warn("could not read latest user sequence") keys, count, err := repo.View.SearchMachineKeys(request) if err != nil { @@ -228,7 +228,7 @@ func (repo *UserRepo) AddressByID(ctx context.Context, userID string) (*usr_mode func (repo *UserRepo) SearchUserMemberships(ctx context.Context, request *usr_model.UserMembershipSearchRequest) (*usr_model.UserMembershipSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) - sequence, sequenceErr := repo.View.GetLatestUserMembershipSequence("") + sequence, sequenceErr := repo.View.GetLatestUserMembershipSequence() logging.Log("EVENT-Dn7sf").OnError(sequenceErr).Warn("could not read latest user sequence") result := handleSearchUserMembershipsPermissions(ctx, request, sequence) diff --git a/internal/management/repository/eventsourcing/eventstore/user_grant.go b/internal/management/repository/eventsourcing/eventstore/user_grant.go index e79e325e6a..878385be54 100644 --- a/internal/management/repository/eventsourcing/eventstore/user_grant.go +++ b/internal/management/repository/eventsourcing/eventstore/user_grant.go @@ -45,7 +45,7 @@ func (repo *UserGrantRepo) UserGrantsByUserID(ctx context.Context, userID string func (repo *UserGrantRepo) SearchUserGrants(ctx context.Context, request *grant_model.UserGrantSearchRequest) (*grant_model.UserGrantSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) - sequence, sequenceErr := repo.View.GetLatestUserGrantSequence("") + sequence, sequenceErr := repo.View.GetLatestUserGrantSequence() logging.Log("EVENT-5Viwf").OnError(sequenceErr).Warn("could not read latest user grant sequence") result := handleSearchUserGrantPermissions(ctx, request, sequence) diff --git a/internal/management/repository/eventsourcing/handler/application.go b/internal/management/repository/eventsourcing/handler/application.go index 442eae59b3..c18a055728 100644 --- a/internal/management/repository/eventsourcing/handler/application.go +++ b/internal/management/repository/eventsourcing/handler/application.go @@ -56,8 +56,8 @@ func (_ *Application) AggregateTypes() []models.AggregateType { return []models.AggregateType{es_model.ProjectAggregate} } -func (a *Application) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := a.view.GetLatestApplicationSequence(string(event.AggregateType)) +func (a *Application) CurrentSequence() (uint64, error) { + sequence, err := a.view.GetLatestApplicationSequence() if err != nil { return 0, err } @@ -65,7 +65,7 @@ func (a *Application) CurrentSequence(event *models.Event) (uint64, error) { } func (a *Application) EventQuery() (*models.SearchQuery, error) { - sequence, err := a.view.GetLatestApplicationSequence("") + sequence, err := a.view.GetLatestApplicationSequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/handler.go b/internal/management/repository/eventsourcing/handler/handler.go index addd360caf..adf3ec26fd 100644 --- a/internal/management/repository/eventsourcing/handler/handler.go +++ b/internal/management/repository/eventsourcing/handler/handler.go @@ -103,6 +103,10 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es handler{view, bulkLimit, configs.cycleDuration("PasswordLockoutPolicy"), errorCount, es}), newOrgIAMPolicy( handler{view, bulkLimit, configs.cycleDuration("OrgIAMPolicy"), errorCount, es}), + newMailTemplate( + handler{view, bulkLimit, configs.cycleDuration("MailTemplate"), errorCount, es}), + newMailText( + handler{view, bulkLimit, configs.cycleDuration("MailText"), errorCount, es}), } } diff --git a/internal/management/repository/eventsourcing/handler/idp_config.go b/internal/management/repository/eventsourcing/handler/idp_config.go index 5fa73038e5..5f86992807 100644 --- a/internal/management/repository/eventsourcing/handler/idp_config.go +++ b/internal/management/repository/eventsourcing/handler/idp_config.go @@ -2,8 +2,8 @@ package handler import ( "github.com/caos/logging" + "github.com/caos/zitadel/internal/eventstore" - "github.com/caos/zitadel/internal/eventstore/models" es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/eventstore/query" "github.com/caos/zitadel/internal/eventstore/spooler" @@ -49,8 +49,8 @@ func (_ *IDPConfig) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate} } -func (m *IDPConfig) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := m.view.GetLatestIDPConfigSequence(string(event.AggregateType)) +func (m *IDPConfig) CurrentSequence() (uint64, error) { + sequence, err := m.view.GetLatestIDPConfigSequence() if err != nil { return 0, err } @@ -58,7 +58,7 @@ func (m *IDPConfig) CurrentSequence(event *models.Event) (uint64, error) { } func (m *IDPConfig) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := m.view.GetLatestIDPConfigSequence("") + sequence, err := m.view.GetLatestIDPConfigSequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/idp_providers.go b/internal/management/repository/eventsourcing/handler/idp_providers.go index 1b5933917b..89d82a1d47 100644 --- a/internal/management/repository/eventsourcing/handler/idp_providers.go +++ b/internal/management/repository/eventsourcing/handler/idp_providers.go @@ -64,8 +64,8 @@ func (_ *IDPProvider) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{model.IAMAggregate, org_es_model.OrgAggregate} } -func (m *IDPProvider) CurrentSequence(event *es_models.Event) (uint64, error) { - sequence, err := m.view.GetLatestIDPProviderSequence(string(event.AggregateType)) +func (m *IDPProvider) CurrentSequence() (uint64, error) { + sequence, err := m.view.GetLatestIDPProviderSequence() if err != nil { return 0, err } @@ -73,7 +73,7 @@ func (m *IDPProvider) CurrentSequence(event *es_models.Event) (uint64, error) { } func (m *IDPProvider) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := m.view.GetLatestIDPProviderSequence("") + sequence, err := m.view.GetLatestIDPProviderSequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/label_policy.go b/internal/management/repository/eventsourcing/handler/label_policy.go index 2cc3ba833e..b56cadbd8a 100644 --- a/internal/management/repository/eventsourcing/handler/label_policy.go +++ b/internal/management/repository/eventsourcing/handler/label_policy.go @@ -48,8 +48,8 @@ func (_ *LabelPolicy) AggregateTypes() []models.AggregateType { return []models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate} } -func (m *LabelPolicy) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := m.view.GetLatestLabelPolicySequence(string(event.AggregateType)) +func (m *LabelPolicy) CurrentSequence() (uint64, error) { + sequence, err := m.view.GetLatestLabelPolicySequence() if err != nil { return 0, err } @@ -57,7 +57,7 @@ func (m *LabelPolicy) CurrentSequence(event *models.Event) (uint64, error) { } func (m *LabelPolicy) EventQuery() (*models.SearchQuery, error) { - sequence, err := m.view.GetLatestLabelPolicySequence("") + sequence, err := m.view.GetLatestLabelPolicySequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/login_policy.go b/internal/management/repository/eventsourcing/handler/login_policy.go index cf8994ff1e..c5a1eae408 100644 --- a/internal/management/repository/eventsourcing/handler/login_policy.go +++ b/internal/management/repository/eventsourcing/handler/login_policy.go @@ -48,8 +48,8 @@ func (_ *LoginPolicy) AggregateTypes() []models.AggregateType { return []models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate} } -func (m *LoginPolicy) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := m.view.GetLatestLoginPolicySequence(string(event.AggregateType)) +func (m *LoginPolicy) CurrentSequence() (uint64, error) { + sequence, err := m.view.GetLatestLoginPolicySequence() if err != nil { return 0, err } @@ -57,7 +57,7 @@ func (m *LoginPolicy) CurrentSequence(event *models.Event) (uint64, error) { } func (m *LoginPolicy) EventQuery() (*models.SearchQuery, error) { - sequence, err := m.view.GetLatestLoginPolicySequence("") + sequence, err := m.view.GetLatestLoginPolicySequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/machine_keys.go b/internal/management/repository/eventsourcing/handler/machine_keys.go index 6758c4f173..cabe5f0cdf 100644 --- a/internal/management/repository/eventsourcing/handler/machine_keys.go +++ b/internal/management/repository/eventsourcing/handler/machine_keys.go @@ -49,8 +49,8 @@ func (_ *MachineKeys) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{model.UserAggregate} } -func (k *MachineKeys) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := k.view.GetLatestMachineKeySequence(string(event.AggregateType)) +func (k *MachineKeys) CurrentSequence() (uint64, error) { + sequence, err := k.view.GetLatestMachineKeySequence() if err != nil { return 0, err } @@ -58,7 +58,7 @@ func (k *MachineKeys) CurrentSequence(event *models.Event) (uint64, error) { } func (d *MachineKeys) EventQuery() (*models.SearchQuery, error) { - sequence, err := d.view.GetLatestMachineKeySequence("") + sequence, err := d.view.GetLatestMachineKeySequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/mail_template.go b/internal/management/repository/eventsourcing/handler/mail_template.go new file mode 100644 index 0000000000..14b529193c --- /dev/null +++ b/internal/management/repository/eventsourcing/handler/mail_template.go @@ -0,0 +1,107 @@ +package handler + +import ( + "github.com/caos/logging" + "github.com/caos/zitadel/internal/eventstore" + iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" + + "github.com/caos/zitadel/internal/eventstore/models" + es_models "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/eventstore/query" + "github.com/caos/zitadel/internal/eventstore/spooler" + iam_model "github.com/caos/zitadel/internal/iam/repository/view/model" + "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" +) + +type MailTemplate struct { + handler + subscription *eventstore.Subscription +} + +func newMailTemplate(handler handler) *MailTemplate { + h := &MailTemplate{ + handler: handler, + } + + h.subscribe() + + return h +} + +func (m *MailTemplate) subscribe() { + m.subscription = m.es.Subscribe(m.AggregateTypes()...) + go func() { + for event := range m.subscription.Events { + query.ReduceEvent(m, event) + } + }() +} + +const ( + mailTemplateTable = "management.mail_templates" +) + +func (m *MailTemplate) ViewModel() string { + return mailTemplateTable +} + +func (_ *MailTemplate) AggregateTypes() []es_models.AggregateType { + return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate} +} + +func (p *MailTemplate) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestMailTemplateSequence() + if err != nil { + return 0, err + } + return sequence.CurrentSequence, nil +} + +func (m *MailTemplate) EventQuery() (*models.SearchQuery, error) { + sequence, err := m.view.GetLatestMailTemplateSequence() + if err != nil { + return nil, err + } + return es_models.NewSearchQuery(). + AggregateTypeFilter(m.AggregateTypes()...). + LatestSequenceFilter(sequence.CurrentSequence), nil +} + +func (m *MailTemplate) Reduce(event *models.Event) (err error) { + switch event.AggregateType { + case model.OrgAggregate, iam_es_model.IAMAggregate: + err = m.processMailTemplate(event) + } + return err +} + +func (m *MailTemplate) processMailTemplate(event *models.Event) (err error) { + template := new(iam_model.MailTemplateView) + switch event.Type { + case iam_es_model.MailTemplateAdded, model.MailTemplateAdded: + err = template.AppendEvent(event) + case iam_es_model.MailTemplateChanged, model.MailTemplateChanged: + template, err = m.view.MailTemplateByAggregateID(event.AggregateID) + if err != nil { + return err + } + err = template.AppendEvent(event) + case model.MailTemplateRemoved: + return m.view.DeleteMailTemplate(event.AggregateID, event) + default: + return m.view.ProcessedMailTemplateSequence(event) + } + if err != nil { + return err + } + return m.view.PutMailTemplate(template, event) +} + +func (m *MailTemplate) OnError(event *models.Event, err error) error { + logging.LogWithFields("SPOOL-4Djo9", "id", event.AggregateID).WithError(err).Warn("something went wrong in label template handler") + return spooler.HandleError(event, err, m.view.GetLatestMailTemplateFailedEvent, m.view.ProcessedMailTemplateFailedEvent, m.view.ProcessedMailTemplateSequence, m.errorCountUntilSkip) +} + +func (o *MailTemplate) OnSuccess() error { + return spooler.HandleSuccess(o.view.UpdateMailTemplateSpoolerRunTimestamp) +} diff --git a/internal/management/repository/eventsourcing/handler/mail_text.go b/internal/management/repository/eventsourcing/handler/mail_text.go new file mode 100644 index 0000000000..9cf65a2e28 --- /dev/null +++ b/internal/management/repository/eventsourcing/handler/mail_text.go @@ -0,0 +1,113 @@ +package handler + +import ( + "github.com/caos/logging" + "github.com/caos/zitadel/internal/eventstore" + iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" + + "github.com/caos/zitadel/internal/eventstore/models" + es_models "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/eventstore/query" + "github.com/caos/zitadel/internal/eventstore/spooler" + iam_model "github.com/caos/zitadel/internal/iam/repository/view/model" + "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" +) + +type MailText struct { + handler + subscription *eventstore.Subscription +} + +func newMailText(handler handler) *MailText { + h := &MailText{ + handler: handler, + } + + h.subscribe() + + return h +} + +func (m *MailText) subscribe() { + m.subscription = m.es.Subscribe(m.AggregateTypes()...) + go func() { + for event := range m.subscription.Events { + query.ReduceEvent(m, event) + } + }() +} + +const ( + mailTextTable = "management.mail_texts" +) + +func (m *MailText) ViewModel() string { + return mailTextTable +} + +func (_ *MailText) AggregateTypes() []es_models.AggregateType { + return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate} +} + +func (p *MailText) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestMailTextSequence() + if err != nil { + return 0, err + } + return sequence.CurrentSequence, nil +} + +func (m *MailText) EventQuery() (*models.SearchQuery, error) { + sequence, err := m.view.GetLatestMailTextSequence() + if err != nil { + return nil, err + } + return es_models.NewSearchQuery(). + AggregateTypeFilter(m.AggregateTypes()...). + LatestSequenceFilter(sequence.CurrentSequence), nil +} + +func (m *MailText) Reduce(event *models.Event) (err error) { + switch event.AggregateType { + case model.OrgAggregate, iam_es_model.IAMAggregate: + err = m.processMailText(event) + } + return err +} + +func (m *MailText) processMailText(event *models.Event) (err error) { + text := new(iam_model.MailTextView) + switch event.Type { + case iam_es_model.MailTextAdded, model.MailTextAdded: + err = text.AppendEvent(event) + case iam_es_model.MailTextChanged, model.MailTextChanged: + err = text.SetData(event) + if err != nil { + return err + } + text, err = m.view.MailTextByIDs(event.AggregateID, text.MailTextType, text.Language) + if err != nil { + return err + } + text.ChangeDate = event.CreationDate + err = text.AppendEvent(event) + case model.MailTextRemoved: + err = text.SetData(event) + return m.view.DeleteMailText(event.AggregateID, text.MailTextType, text.Language, event) + default: + return m.view.ProcessedMailTextSequence(event) + } + if err != nil { + return err + } + return m.view.PutMailText(text, event) +} + +func (m *MailText) OnError(event *models.Event, err error) error { + logging.LogWithFields("SPOOL-4Djo9", "id", event.AggregateID).WithError(err).Warn("something went wrong in label text handler") + return spooler.HandleError(event, err, m.view.GetLatestMailTextFailedEvent, m.view.ProcessedMailTextFailedEvent, m.view.ProcessedMailTextSequence, m.errorCountUntilSkip) +} + +func (o *MailText) OnSuccess() error { + return spooler.HandleSuccess(o.view.UpdateMailTextSpoolerRunTimestamp) +} diff --git a/internal/management/repository/eventsourcing/handler/org.go b/internal/management/repository/eventsourcing/handler/org.go index a4f6eb211d..af950ffa8c 100644 --- a/internal/management/repository/eventsourcing/handler/org.go +++ b/internal/management/repository/eventsourcing/handler/org.go @@ -2,8 +2,8 @@ package handler import ( "github.com/caos/logging" + "github.com/caos/zitadel/internal/eventstore" - "github.com/caos/zitadel/internal/eventstore/models" es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/eventstore/query" "github.com/caos/zitadel/internal/eventstore/spooler" @@ -48,8 +48,8 @@ func (_ *Org) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{model.OrgAggregate} } -func (o *Org) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := o.view.GetLatestOrgSequence(string(event.AggregateType)) +func (o *Org) CurrentSequence() (uint64, error) { + sequence, err := o.view.GetLatestOrgSequence() if err != nil { return 0, err } @@ -57,7 +57,7 @@ func (o *Org) CurrentSequence(event *models.Event) (uint64, error) { } func (o *Org) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := o.view.GetLatestOrgSequence("") + sequence, err := o.view.GetLatestOrgSequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/org_domain.go b/internal/management/repository/eventsourcing/handler/org_domain.go index 9a7dedb5ee..963f518592 100644 --- a/internal/management/repository/eventsourcing/handler/org_domain.go +++ b/internal/management/repository/eventsourcing/handler/org_domain.go @@ -47,8 +47,8 @@ func (_ *OrgDomain) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{model.OrgAggregate} } -func (p *OrgDomain) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestOrgDomainSequence(string(event.AggregateType)) +func (p *OrgDomain) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestOrgDomainSequence() if err != nil { return 0, err } @@ -56,7 +56,7 @@ func (p *OrgDomain) CurrentSequence(event *models.Event) (uint64, error) { } func (d *OrgDomain) EventQuery() (*models.SearchQuery, error) { - sequence, err := d.view.GetLatestOrgDomainSequence("") + sequence, err := d.view.GetLatestOrgDomainSequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/org_iam_policy.go b/internal/management/repository/eventsourcing/handler/org_iam_policy.go index 796652bbb4..636b37ff6f 100644 --- a/internal/management/repository/eventsourcing/handler/org_iam_policy.go +++ b/internal/management/repository/eventsourcing/handler/org_iam_policy.go @@ -48,8 +48,8 @@ func (_ *OrgIAMPolicy) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate} } -func (p *OrgIAMPolicy) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestOrgIAMPolicySequence(string(event.AggregateType)) +func (p *OrgIAMPolicy) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestOrgIAMPolicySequence() if err != nil { return 0, err } @@ -57,7 +57,7 @@ func (p *OrgIAMPolicy) CurrentSequence(event *models.Event) (uint64, error) { } func (m *OrgIAMPolicy) EventQuery() (*models.SearchQuery, error) { - sequence, err := m.view.GetLatestOrgIAMPolicySequence("") + sequence, err := m.view.GetLatestOrgIAMPolicySequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/org_member.go b/internal/management/repository/eventsourcing/handler/org_member.go index cf3e1b6499..f4e8743b6d 100644 --- a/internal/management/repository/eventsourcing/handler/org_member.go +++ b/internal/management/repository/eventsourcing/handler/org_member.go @@ -57,8 +57,8 @@ func (_ *OrgMember) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{model.OrgAggregate, usr_es_model.UserAggregate} } -func (p *OrgMember) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestOrgMemberSequence(string(event.AggregateType)) +func (p *OrgMember) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestOrgMemberSequence() if err != nil { return 0, err } @@ -66,7 +66,7 @@ func (p *OrgMember) CurrentSequence(event *models.Event) (uint64, error) { } func (m *OrgMember) EventQuery() (*models.SearchQuery, error) { - sequence, err := m.view.GetLatestOrgMemberSequence("") + sequence, err := m.view.GetLatestOrgMemberSequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/password_age_policy.go b/internal/management/repository/eventsourcing/handler/password_age_policy.go index eee2e2711c..1e5bc2ba75 100644 --- a/internal/management/repository/eventsourcing/handler/password_age_policy.go +++ b/internal/management/repository/eventsourcing/handler/password_age_policy.go @@ -48,8 +48,8 @@ func (_ *PasswordAgePolicy) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate} } -func (o *PasswordAgePolicy) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := o.view.GetLatestPasswordAgePolicySequence(string(event.AggregateType)) +func (o *PasswordAgePolicy) CurrentSequence() (uint64, error) { + sequence, err := o.view.GetLatestPasswordAgePolicySequence() if err != nil { return 0, err } @@ -57,7 +57,7 @@ func (o *PasswordAgePolicy) CurrentSequence(event *models.Event) (uint64, error) } func (p *PasswordAgePolicy) EventQuery() (*models.SearchQuery, error) { - sequence, err := p.view.GetLatestPasswordAgePolicySequence("") + sequence, err := p.view.GetLatestPasswordAgePolicySequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/password_complexity_policy.go b/internal/management/repository/eventsourcing/handler/password_complexity_policy.go index d2d14c885d..d4935e88c5 100644 --- a/internal/management/repository/eventsourcing/handler/password_complexity_policy.go +++ b/internal/management/repository/eventsourcing/handler/password_complexity_policy.go @@ -48,8 +48,8 @@ func (_ *PasswordComplexityPolicy) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate} } -func (p *PasswordComplexityPolicy) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestPasswordComplexityPolicySequence(string(event.AggregateType)) +func (p *PasswordComplexityPolicy) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestPasswordComplexityPolicySequence() if err != nil { return 0, err } @@ -57,7 +57,7 @@ func (p *PasswordComplexityPolicy) CurrentSequence(event *models.Event) (uint64, } func (p *PasswordComplexityPolicy) EventQuery() (*models.SearchQuery, error) { - sequence, err := p.view.GetLatestPasswordComplexityPolicySequence("") + sequence, err := p.view.GetLatestPasswordComplexityPolicySequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/password_lockout_policy.go b/internal/management/repository/eventsourcing/handler/password_lockout_policy.go index 19e7c9c0b6..89103d6b84 100644 --- a/internal/management/repository/eventsourcing/handler/password_lockout_policy.go +++ b/internal/management/repository/eventsourcing/handler/password_lockout_policy.go @@ -49,8 +49,8 @@ func (_ *PasswordLockoutPolicy) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate} } -func (p *PasswordLockoutPolicy) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestPasswordLockoutPolicySequence(string(event.AggregateType)) +func (p *PasswordLockoutPolicy) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestPasswordLockoutPolicySequence() if err != nil { return 0, err } @@ -58,7 +58,7 @@ func (p *PasswordLockoutPolicy) CurrentSequence(event *models.Event) (uint64, er } func (p *PasswordLockoutPolicy) EventQuery() (*models.SearchQuery, error) { - sequence, err := p.view.GetLatestPasswordLockoutPolicySequence("") + sequence, err := p.view.GetLatestPasswordLockoutPolicySequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/project.go b/internal/management/repository/eventsourcing/handler/project.go index 51331d44ee..d123b62091 100644 --- a/internal/management/repository/eventsourcing/handler/project.go +++ b/internal/management/repository/eventsourcing/handler/project.go @@ -48,8 +48,8 @@ func (_ *Project) AggregateTypes() []models.AggregateType { return []models.AggregateType{es_model.ProjectAggregate} } -func (p *Project) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestProjectSequence(string(event.AggregateType)) +func (p *Project) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestProjectSequence() if err != nil { return 0, err } @@ -57,7 +57,7 @@ func (p *Project) CurrentSequence(event *models.Event) (uint64, error) { } func (p *Project) EventQuery() (*models.SearchQuery, error) { - sequence, err := p.view.GetLatestProjectSequence("") + sequence, err := p.view.GetLatestProjectSequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/project_grant.go b/internal/management/repository/eventsourcing/handler/project_grant.go index 918eb54f56..1c96a8a80b 100644 --- a/internal/management/repository/eventsourcing/handler/project_grant.go +++ b/internal/management/repository/eventsourcing/handler/project_grant.go @@ -61,8 +61,8 @@ func (_ *ProjectGrant) AggregateTypes() []models.AggregateType { return []models.AggregateType{es_model.ProjectAggregate} } -func (p *ProjectGrant) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestProjectGrantSequence(string(event.AggregateType)) +func (p *ProjectGrant) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestProjectGrantSequence() if err != nil { return 0, err } @@ -70,7 +70,7 @@ func (p *ProjectGrant) CurrentSequence(event *models.Event) (uint64, error) { } func (p *ProjectGrant) EventQuery() (*models.SearchQuery, error) { - sequence, err := p.view.GetLatestProjectGrantSequence("") + sequence, err := p.view.GetLatestProjectGrantSequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/project_grant_member.go b/internal/management/repository/eventsourcing/handler/project_grant_member.go index 159be6d870..6897568ea8 100644 --- a/internal/management/repository/eventsourcing/handler/project_grant_member.go +++ b/internal/management/repository/eventsourcing/handler/project_grant_member.go @@ -58,8 +58,8 @@ func (_ *ProjectGrantMember) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{proj_es_model.ProjectAggregate, usr_es_model.UserAggregate} } -func (p *ProjectGrantMember) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestProjectGrantMemberSequence(string(event.AggregateType)) +func (p *ProjectGrantMember) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestProjectGrantMemberSequence() if err != nil { return 0, err } @@ -67,7 +67,7 @@ func (p *ProjectGrantMember) CurrentSequence(event *models.Event) (uint64, error } func (p *ProjectGrantMember) EventQuery() (*models.SearchQuery, error) { - sequence, err := p.view.GetLatestProjectGrantMemberSequence("") + sequence, err := p.view.GetLatestProjectGrantMemberSequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/project_member.go b/internal/management/repository/eventsourcing/handler/project_member.go index 721f42e9d8..0e8bf87f1a 100644 --- a/internal/management/repository/eventsourcing/handler/project_member.go +++ b/internal/management/repository/eventsourcing/handler/project_member.go @@ -58,8 +58,8 @@ func (_ *ProjectMember) AggregateTypes() []models.AggregateType { return []models.AggregateType{proj_es_model.ProjectAggregate, usr_es_model.UserAggregate} } -func (p *ProjectMember) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestProjectMemberSequence(string(event.AggregateType)) +func (p *ProjectMember) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestProjectMemberSequence() if err != nil { return 0, err } @@ -67,7 +67,7 @@ func (p *ProjectMember) CurrentSequence(event *models.Event) (uint64, error) { } func (p *ProjectMember) EventQuery() (*models.SearchQuery, error) { - sequence, err := p.view.GetLatestProjectMemberSequence("") + sequence, err := p.view.GetLatestProjectMemberSequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/project_role.go b/internal/management/repository/eventsourcing/handler/project_role.go index 3d89ba4a9f..b6f64f075a 100644 --- a/internal/management/repository/eventsourcing/handler/project_role.go +++ b/internal/management/repository/eventsourcing/handler/project_role.go @@ -54,8 +54,8 @@ func (_ *ProjectRole) AggregateTypes() []models.AggregateType { return []models.AggregateType{es_model.ProjectAggregate} } -func (p *ProjectRole) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := p.view.GetLatestProjectRoleSequence(string(event.AggregateType)) +func (p *ProjectRole) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestProjectRoleSequence() if err != nil { return 0, err } @@ -63,7 +63,7 @@ func (p *ProjectRole) CurrentSequence(event *models.Event) (uint64, error) { } func (p *ProjectRole) EventQuery() (*models.SearchQuery, error) { - sequence, err := p.view.GetLatestProjectRoleSequence("") + sequence, err := p.view.GetLatestProjectRoleSequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/user.go b/internal/management/repository/eventsourcing/handler/user.go index bf415d1602..fdfe7f44af 100644 --- a/internal/management/repository/eventsourcing/handler/user.go +++ b/internal/management/repository/eventsourcing/handler/user.go @@ -64,8 +64,8 @@ func (_ *User) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{es_model.UserAggregate, org_es_model.OrgAggregate} } -func (u *User) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := u.view.GetLatestUserSequence(string(event.AggregateType)) +func (u *User) CurrentSequence() (uint64, error) { + sequence, err := u.view.GetLatestUserSequence() if err != nil { return 0, err } @@ -73,7 +73,7 @@ func (u *User) CurrentSequence(event *models.Event) (uint64, error) { } func (u *User) EventQuery() (*models.SearchQuery, error) { - sequence, err := u.view.GetLatestUserSequence("") + sequence, err := u.view.GetLatestUserSequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/user_external_idps.go b/internal/management/repository/eventsourcing/handler/user_external_idps.go index 059a15c9bd..b25c32d803 100644 --- a/internal/management/repository/eventsourcing/handler/user_external_idps.go +++ b/internal/management/repository/eventsourcing/handler/user_external_idps.go @@ -4,10 +4,10 @@ import ( "context" "github.com/caos/logging" + "github.com/caos/zitadel/internal/config/systemdefaults" caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" - "github.com/caos/zitadel/internal/eventstore/models" es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/eventstore/query" "github.com/caos/zitadel/internal/eventstore/spooler" @@ -68,8 +68,8 @@ func (_ *ExternalIDP) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{model.UserAggregate, iam_es_model.IAMAggregate, org_es_model.OrgAggregate} } -func (i *ExternalIDP) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := i.view.GetLatestExternalIDPSequence(string(event.AggregateType)) +func (i *ExternalIDP) CurrentSequence() (uint64, error) { + sequence, err := i.view.GetLatestExternalIDPSequence() if err != nil { return 0, err } @@ -77,7 +77,7 @@ func (i *ExternalIDP) CurrentSequence(event *models.Event) (uint64, error) { } func (i *ExternalIDP) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := i.view.GetLatestExternalIDPSequence("") + sequence, err := i.view.GetLatestExternalIDPSequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/user_grant.go b/internal/management/repository/eventsourcing/handler/user_grant.go index a4f0869783..c9fc00e3c6 100644 --- a/internal/management/repository/eventsourcing/handler/user_grant.go +++ b/internal/management/repository/eventsourcing/handler/user_grant.go @@ -4,8 +4,8 @@ import ( "context" "github.com/caos/logging" + "github.com/caos/zitadel/internal/eventstore" - "github.com/caos/zitadel/internal/eventstore/models" es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/eventstore/query" "github.com/caos/zitadel/internal/eventstore/spooler" @@ -68,8 +68,8 @@ func (_ *UserGrant) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{grant_es_model.UserGrantAggregate, usr_es_model.UserAggregate, proj_es_model.ProjectAggregate} } -func (u *UserGrant) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := u.view.GetLatestUserGrantSequence(string(event.AggregateType)) +func (u *UserGrant) CurrentSequence() (uint64, error) { + sequence, err := u.view.GetLatestUserGrantSequence() if err != nil { return 0, err } @@ -77,7 +77,7 @@ func (u *UserGrant) CurrentSequence(event *models.Event) (uint64, error) { } func (u *UserGrant) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := u.view.GetLatestUserGrantSequence("") + sequence, err := u.view.GetLatestUserGrantSequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/handler/user_membership.go b/internal/management/repository/eventsourcing/handler/user_membership.go index 9358acc4e2..520479f665 100644 --- a/internal/management/repository/eventsourcing/handler/user_membership.go +++ b/internal/management/repository/eventsourcing/handler/user_membership.go @@ -4,8 +4,8 @@ import ( "context" "github.com/caos/logging" + "github.com/caos/zitadel/internal/eventstore" - "github.com/caos/zitadel/internal/eventstore/models" es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/eventstore/query" "github.com/caos/zitadel/internal/eventstore/spooler" @@ -64,8 +64,8 @@ func (_ *UserMembership) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{iam_es_model.IAMAggregate, org_es_model.OrgAggregate, proj_es_model.ProjectAggregate, model.UserAggregate} } -func (u *UserMembership) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := u.view.GetLatestUserMembershipSequence(string(event.AggregateType)) +func (u *UserMembership) CurrentSequence() (uint64, error) { + sequence, err := u.view.GetLatestUserMembershipSequence() if err != nil { return 0, err } @@ -73,7 +73,7 @@ func (u *UserMembership) CurrentSequence(event *models.Event) (uint64, error) { } func (m *UserMembership) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := m.view.GetLatestUserMembershipSequence("") + sequence, err := m.view.GetLatestUserMembershipSequence() if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/view/application.go b/internal/management/repository/eventsourcing/view/application.go index c9b4a6fbd0..45a5f344ac 100644 --- a/internal/management/repository/eventsourcing/view/application.go +++ b/internal/management/repository/eventsourcing/view/application.go @@ -53,8 +53,8 @@ func (v *View) DeleteApplicationsByProjectID(projectID string) error { return view.DeleteApplicationsByProjectID(v.Db, applicationTable, projectID) } -func (v *View) GetLatestApplicationSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(applicationTable, aggregateType) +func (v *View) GetLatestApplicationSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(applicationTable) } func (v *View) ProcessedApplicationSequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/external_idps.go b/internal/management/repository/eventsourcing/view/external_idps.go index 0b8eb3648e..24fe60c26e 100644 --- a/internal/management/repository/eventsourcing/view/external_idps.go +++ b/internal/management/repository/eventsourcing/view/external_idps.go @@ -64,8 +64,8 @@ func (v *View) DeleteExternalIDPsByUserID(userID string, event *models.Event) er } return v.ProcessedExternalIDPSequence(event) } -func (v *View) GetLatestExternalIDPSequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(externalIDPTable, aggregateType) +func (v *View) GetLatestExternalIDPSequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(externalIDPTable) } func (v *View) ProcessedExternalIDPSequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/idp_configs.go b/internal/management/repository/eventsourcing/view/idp_configs.go index 5770f36b38..ca759c6f38 100644 --- a/internal/management/repository/eventsourcing/view/idp_configs.go +++ b/internal/management/repository/eventsourcing/view/idp_configs.go @@ -37,8 +37,8 @@ func (v *View) DeleteIDPConfig(idpID string, event *models.Event) error { return v.ProcessedIDPConfigSequence(event) } -func (v *View) GetLatestIDPConfigSequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(idpConfigTable, aggregateType) +func (v *View) GetLatestIDPConfigSequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(idpConfigTable) } func (v *View) ProcessedIDPConfigSequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/idp_providers.go b/internal/management/repository/eventsourcing/view/idp_providers.go index a293ec1637..f73a4720f8 100644 --- a/internal/management/repository/eventsourcing/view/idp_providers.go +++ b/internal/management/repository/eventsourcing/view/idp_providers.go @@ -57,8 +57,8 @@ func (v *View) DeleteIDPProvidersByAggregateID(aggregateID string, event *models return v.ProcessedIDPProviderSequence(event) } -func (v *View) GetLatestIDPProviderSequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(idpProviderTable, aggregateType) +func (v *View) GetLatestIDPProviderSequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(idpProviderTable) } func (v *View) ProcessedIDPProviderSequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/label_policies.go b/internal/management/repository/eventsourcing/view/label_policies.go index 05bb9550a4..17cb603d25 100644 --- a/internal/management/repository/eventsourcing/view/label_policies.go +++ b/internal/management/repository/eventsourcing/view/label_policies.go @@ -32,8 +32,8 @@ func (v *View) DeleteLabelPolicy(aggregateID string, event *models.Event) error return v.ProcessedLabelPolicySequence(event) } -func (v *View) GetLatestLabelPolicySequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(labelPolicyTable, aggregateType) +func (v *View) GetLatestLabelPolicySequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(labelPolicyTable) } func (v *View) ProcessedLabelPolicySequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/login_policies.go b/internal/management/repository/eventsourcing/view/login_policies.go index 56e6e80f8f..1788a622b3 100644 --- a/internal/management/repository/eventsourcing/view/login_policies.go +++ b/internal/management/repository/eventsourcing/view/login_policies.go @@ -32,8 +32,8 @@ func (v *View) DeleteLoginPolicy(aggregateID string, event *models.Event) error return v.ProcessedLoginPolicySequence(event) } -func (v *View) GetLatestLoginPolicySequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(loginPolicyTable, aggregateType) +func (v *View) GetLatestLoginPolicySequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(loginPolicyTable) } func (v *View) ProcessedLoginPolicySequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/machine_keys.go b/internal/management/repository/eventsourcing/view/machine_keys.go index c861cfd58c..075e15fe8e 100644 --- a/internal/management/repository/eventsourcing/view/machine_keys.go +++ b/internal/management/repository/eventsourcing/view/machine_keys.go @@ -49,8 +49,8 @@ func (v *View) DeleteMachineKeysByUserID(userID string, event *models.Event) err return v.ProcessedMachineKeySequence(event) } -func (v *View) GetLatestMachineKeySequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(machineKeyTable, aggregateType) +func (v *View) GetLatestMachineKeySequence() (*repository.CurrentSequence, error) { + return v.latestSequence(machineKeyTable) } func (v *View) ProcessedMachineKeySequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/mail_templates.go b/internal/management/repository/eventsourcing/view/mail_templates.go new file mode 100644 index 0000000000..34c3ab2249 --- /dev/null +++ b/internal/management/repository/eventsourcing/view/mail_templates.go @@ -0,0 +1,53 @@ +package view + +import ( + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/iam/repository/view" + "github.com/caos/zitadel/internal/iam/repository/view/model" + global_view "github.com/caos/zitadel/internal/view/repository" +) + +const ( + mailTemplateTable = "management.mail_templates" +) + +func (v *View) MailTemplateByAggregateID(aggregateID string) (*model.MailTemplateView, error) { + return view.GetMailTemplateByAggregateID(v.Db, mailTemplateTable, aggregateID) +} + +func (v *View) PutMailTemplate(template *model.MailTemplateView, event *models.Event) error { + err := view.PutMailTemplate(v.Db, mailTemplateTable, template) + if err != nil { + return err + } + return v.ProcessedMailTemplateSequence(event) +} + +func (v *View) DeleteMailTemplate(aggregateID string, event *models.Event) error { + err := view.DeleteMailTemplate(v.Db, mailTemplateTable, aggregateID) + if err != nil && !errors.IsNotFound(err) { + return err + } + return v.ProcessedMailTemplateSequence(event) +} + +func (v *View) GetLatestMailTemplateSequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(mailTemplateTable) +} + +func (v *View) ProcessedMailTemplateSequence(event *models.Event) error { + return v.saveCurrentSequence(mailTemplateTable, event) +} + +func (v *View) UpdateMailTemplateSpoolerRunTimestamp() error { + return v.updateSpoolerRunSequence(mailTemplateTable) +} + +func (v *View) GetLatestMailTemplateFailedEvent(sequence uint64) (*global_view.FailedEvent, error) { + return v.latestFailedEvent(mailTemplateTable, sequence) +} + +func (v *View) ProcessedMailTemplateFailedEvent(failedEvent *global_view.FailedEvent) error { + return v.saveFailedEvent(failedEvent) +} diff --git a/internal/management/repository/eventsourcing/view/mail_texts.go b/internal/management/repository/eventsourcing/view/mail_texts.go new file mode 100644 index 0000000000..c9ab7cd443 --- /dev/null +++ b/internal/management/repository/eventsourcing/view/mail_texts.go @@ -0,0 +1,57 @@ +package view + +import ( + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/iam/repository/view" + "github.com/caos/zitadel/internal/iam/repository/view/model" + global_view "github.com/caos/zitadel/internal/view/repository" +) + +const ( + mailTextTable = "management.mail_texts" +) + +func (v *View) MailTextsByAggregateID(aggregateID string) ([]*model.MailTextView, error) { + return view.GetMailTexts(v.Db, mailTextTable, aggregateID) +} + +func (v *View) MailTextByIDs(aggregateID string, textType string, language string) (*model.MailTextView, error) { + return view.GetMailTextByIDs(v.Db, mailTextTable, aggregateID, textType, language) +} + +func (v *View) PutMailText(template *model.MailTextView, event *models.Event) error { + err := view.PutMailText(v.Db, mailTextTable, template) + if err != nil { + return err + } + return v.ProcessedMailTextSequence(event) +} + +func (v *View) DeleteMailText(aggregateID string, textType string, language string, event *models.Event) error { + err := view.DeleteMailText(v.Db, mailTextTable, aggregateID, textType, language) + if err != nil && !errors.IsNotFound(err) { + return err + } + return v.ProcessedMailTextSequence(event) +} + +func (v *View) GetLatestMailTextSequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(mailTextTable) +} + +func (v *View) ProcessedMailTextSequence(event *models.Event) error { + return v.saveCurrentSequence(mailTextTable, event) +} + +func (v *View) UpdateMailTextSpoolerRunTimestamp() error { + return v.updateSpoolerRunSequence(mailTextTable) +} + +func (v *View) GetLatestMailTextFailedEvent(sequence uint64) (*global_view.FailedEvent, error) { + return v.latestFailedEvent(mailTextTable, sequence) +} + +func (v *View) ProcessedMailTextFailedEvent(failedEvent *global_view.FailedEvent) error { + return v.saveFailedEvent(failedEvent) +} diff --git a/internal/management/repository/eventsourcing/view/org.go b/internal/management/repository/eventsourcing/view/org.go index 3a53b92031..72323eeb07 100644 --- a/internal/management/repository/eventsourcing/view/org.go +++ b/internal/management/repository/eventsourcing/view/org.go @@ -35,8 +35,8 @@ func (v *View) UpdateOrgSpoolerRunTimestamp() error { return v.updateSpoolerRunSequence(orgTable) } -func (v *View) GetLatestOrgSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(orgTable, aggregateType) +func (v *View) GetLatestOrgSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(orgTable) } func (v *View) ProcessedOrgSequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/org_domain.go b/internal/management/repository/eventsourcing/view/org_domain.go index 45ee4ad912..6819980dea 100644 --- a/internal/management/repository/eventsourcing/view/org_domain.go +++ b/internal/management/repository/eventsourcing/view/org_domain.go @@ -53,8 +53,8 @@ func (v *View) DeleteOrgDomain(orgID, domain string, event *models.Event) error return v.ProcessedOrgDomainSequence(event) } -func (v *View) GetLatestOrgDomainSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(orgDomainTable, aggregateType) +func (v *View) GetLatestOrgDomainSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(orgDomainTable) } func (v *View) ProcessedOrgDomainSequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/org_iam_policy.go b/internal/management/repository/eventsourcing/view/org_iam_policy.go index 90d3de2b9c..266c2e0371 100644 --- a/internal/management/repository/eventsourcing/view/org_iam_policy.go +++ b/internal/management/repository/eventsourcing/view/org_iam_policy.go @@ -32,8 +32,8 @@ func (v *View) DeleteOrgIAMPolicy(aggregateID string, event *models.Event) error return v.ProcessedOrgIAMPolicySequence(event) } -func (v *View) GetLatestOrgIAMPolicySequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(orgIAMPolicyTable, aggregateType) +func (v *View) GetLatestOrgIAMPolicySequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(orgIAMPolicyTable) } func (v *View) ProcessedOrgIAMPolicySequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/org_member.go b/internal/management/repository/eventsourcing/view/org_member.go index ee6deac739..0f69399786 100644 --- a/internal/management/repository/eventsourcing/view/org_member.go +++ b/internal/management/repository/eventsourcing/view/org_member.go @@ -57,8 +57,8 @@ func (v *View) DeleteOrgMembersByUserID(userID string, event *models.Event) erro return v.ProcessedOrgMemberSequence(event) } -func (v *View) GetLatestOrgMemberSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(orgMemberTable, aggregateType) +func (v *View) GetLatestOrgMemberSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(orgMemberTable) } func (v *View) ProcessedOrgMemberSequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/password_age_policy.go b/internal/management/repository/eventsourcing/view/password_age_policy.go index e1bd56a596..5fc99367cf 100644 --- a/internal/management/repository/eventsourcing/view/password_age_policy.go +++ b/internal/management/repository/eventsourcing/view/password_age_policy.go @@ -32,8 +32,8 @@ func (v *View) DeletePasswordAgePolicy(aggregateID string, event *models.Event) return v.ProcessedPasswordAgePolicySequence(event) } -func (v *View) GetLatestPasswordAgePolicySequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(passwordAgePolicyTable, aggregateType) +func (v *View) GetLatestPasswordAgePolicySequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(passwordAgePolicyTable) } func (v *View) ProcessedPasswordAgePolicySequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/password_complexity_policy.go b/internal/management/repository/eventsourcing/view/password_complexity_policy.go index 80d9e2d90d..db24d4ab2a 100644 --- a/internal/management/repository/eventsourcing/view/password_complexity_policy.go +++ b/internal/management/repository/eventsourcing/view/password_complexity_policy.go @@ -32,8 +32,8 @@ func (v *View) DeletePasswordComplexityPolicy(aggregateID string, event *models. return v.ProcessedPasswordComplexityPolicySequence(event) } -func (v *View) GetLatestPasswordComplexityPolicySequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(passwordComplexityPolicyTable, aggregateType) +func (v *View) GetLatestPasswordComplexityPolicySequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(passwordComplexityPolicyTable) } func (v *View) ProcessedPasswordComplexityPolicySequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/password_lockout_policy.go b/internal/management/repository/eventsourcing/view/password_lockout_policy.go index 549f704c75..d3e0ea0e16 100644 --- a/internal/management/repository/eventsourcing/view/password_lockout_policy.go +++ b/internal/management/repository/eventsourcing/view/password_lockout_policy.go @@ -32,8 +32,8 @@ func (v *View) DeletePasswordLockoutPolicy(aggregateID string, event *models.Eve return v.ProcessedPasswordLockoutPolicySequence(event) } -func (v *View) GetLatestPasswordLockoutPolicySequence(aggregateType string) (*global_view.CurrentSequence, error) { - return v.latestSequence(passwordLockoutPolicyTable, aggregateType) +func (v *View) GetLatestPasswordLockoutPolicySequence() (*global_view.CurrentSequence, error) { + return v.latestSequence(passwordLockoutPolicyTable) } func (v *View) ProcessedPasswordLockoutPolicySequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/project.go b/internal/management/repository/eventsourcing/view/project.go index f5ac609ddc..d32f7c577d 100644 --- a/internal/management/repository/eventsourcing/view/project.go +++ b/internal/management/repository/eventsourcing/view/project.go @@ -37,8 +37,8 @@ func (v *View) DeleteProject(projectID string, event *models.Event) error { return v.ProcessedProjectSequence(event) } -func (v *View) GetLatestProjectSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(projectTable, aggregateType) +func (v *View) GetLatestProjectSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(projectTable) } func (v *View) ProcessedProjectSequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/project_grant.go b/internal/management/repository/eventsourcing/view/project_grant.go index ab54927a30..08eb4bf444 100644 --- a/internal/management/repository/eventsourcing/view/project_grant.go +++ b/internal/management/repository/eventsourcing/view/project_grant.go @@ -60,8 +60,8 @@ func (v *View) DeleteProjectGrantsByProjectID(projectID string) error { return view.DeleteProjectGrantsByProjectID(v.Db, grantedProjectTable, projectID) } -func (v *View) GetLatestProjectGrantSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(grantedProjectTable, aggregateType) +func (v *View) GetLatestProjectGrantSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(grantedProjectTable) } func (v *View) ProcessedProjectGrantSequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/project_grant_member.go b/internal/management/repository/eventsourcing/view/project_grant_member.go index 7634cefbf5..e682ef25da 100644 --- a/internal/management/repository/eventsourcing/view/project_grant_member.go +++ b/internal/management/repository/eventsourcing/view/project_grant_member.go @@ -57,8 +57,8 @@ func (v *View) DeleteProjectGrantMembersByProjectID(projectID string) error { return view.DeleteProjectGrantMembersByProjectID(v.Db, projectGrantMemberTable, projectID) } -func (v *View) GetLatestProjectGrantMemberSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(projectGrantMemberTable, aggregateType) +func (v *View) GetLatestProjectGrantMemberSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(projectGrantMemberTable) } func (v *View) ProcessedProjectGrantMemberSequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/project_member.go b/internal/management/repository/eventsourcing/view/project_member.go index 09f3b31518..327632c789 100644 --- a/internal/management/repository/eventsourcing/view/project_member.go +++ b/internal/management/repository/eventsourcing/view/project_member.go @@ -57,8 +57,8 @@ func (v *View) DeleteProjectMembersByProjectID(projectID string) error { return view.DeleteProjectMembersByProjectID(v.Db, projectMemberTable, projectID) } -func (v *View) GetLatestProjectMemberSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(projectMemberTable, aggregateType) +func (v *View) GetLatestProjectMemberSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(projectMemberTable) } func (v *View) ProcessedProjectMemberSequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/project_role.go b/internal/management/repository/eventsourcing/view/project_role.go index 5b251fa24b..68da7611fd 100644 --- a/internal/management/repository/eventsourcing/view/project_role.go +++ b/internal/management/repository/eventsourcing/view/project_role.go @@ -53,8 +53,8 @@ func (v *View) DeleteProjectRolesByProjectID(projectID string) error { return view.DeleteProjectRolesByProjectID(v.Db, projectRoleTable, projectID) } -func (v *View) GetLatestProjectRoleSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(projectRoleTable, aggregateType) +func (v *View) GetLatestProjectRoleSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(projectRoleTable) } func (v *View) ProcessedProjectRoleSequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/sequence.go b/internal/management/repository/eventsourcing/view/sequence.go index 808ff58216..4cff5fc9eb 100644 --- a/internal/management/repository/eventsourcing/view/sequence.go +++ b/internal/management/repository/eventsourcing/view/sequence.go @@ -12,15 +12,15 @@ const ( ) func (v *View) saveCurrentSequence(viewName string, event *models.Event) error { - return repository.SaveCurrentSequence(v.Db, sequencesTable, viewName, string(event.AggregateType), event.Sequence, event.CreationDate) + return repository.SaveCurrentSequence(v.Db, sequencesTable, viewName, event.Sequence, event.CreationDate) } -func (v *View) latestSequence(viewName, aggregateType string) (*repository.CurrentSequence, error) { - return repository.LatestSequence(v.Db, sequencesTable, viewName, aggregateType) +func (v *View) latestSequence(viewName string) (*repository.CurrentSequence, error) { + return repository.LatestSequence(v.Db, sequencesTable, viewName) } func (v *View) updateSpoolerRunSequence(viewName string) error { - currentSequence, err := repository.LatestSequence(v.Db, sequencesTable, viewName, "") + currentSequence, err := repository.LatestSequence(v.Db, sequencesTable, viewName) if err != nil { return err } diff --git a/internal/management/repository/eventsourcing/view/user.go b/internal/management/repository/eventsourcing/view/user.go index d589b546f7..8622d7a381 100644 --- a/internal/management/repository/eventsourcing/view/user.go +++ b/internal/management/repository/eventsourcing/view/user.go @@ -65,8 +65,8 @@ func (v *View) DeleteUser(userID string, event *models.Event) error { return v.ProcessedUserSequence(event) } -func (v *View) GetLatestUserSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(userTable, aggregateType) +func (v *View) GetLatestUserSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(userTable) } func (v *View) ProcessedUserSequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/user_grant.go b/internal/management/repository/eventsourcing/view/user_grant.go index 15dd3220d2..1e2f6d587f 100644 --- a/internal/management/repository/eventsourcing/view/user_grant.go +++ b/internal/management/repository/eventsourcing/view/user_grant.go @@ -65,8 +65,8 @@ func (v *View) DeleteUserGrant(grantID string, event *models.Event) error { return v.ProcessedUserGrantSequence(event) } -func (v *View) GetLatestUserGrantSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(userGrantTable, aggregateType) +func (v *View) GetLatestUserGrantSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(userGrantTable) } func (v *View) ProcessedUserGrantSequence(event *models.Event) error { diff --git a/internal/management/repository/eventsourcing/view/user_membership.go b/internal/management/repository/eventsourcing/view/user_membership.go index 90f64906a7..0187cd62bc 100644 --- a/internal/management/repository/eventsourcing/view/user_membership.go +++ b/internal/management/repository/eventsourcing/view/user_membership.go @@ -73,8 +73,8 @@ func (v *View) DeleteUserMembershipsByAggregateIDAndObjectID(aggregateID, object return v.ProcessedUserMembershipSequence(event) } -func (v *View) GetLatestUserMembershipSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(userMembershipTable, aggregateType) +func (v *View) GetLatestUserMembershipSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(userMembershipTable) } func (v *View) ProcessedUserMembershipSequence(event *models.Event) error { diff --git a/internal/management/repository/org.go b/internal/management/repository/org.go index 1538bc7737..1292eed15a 100644 --- a/internal/management/repository/org.go +++ b/internal/management/repository/org.go @@ -38,4 +38,16 @@ type OrgRepository interface { GetPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error) GetDefaultPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error) + + GetDefaultMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error) + GetMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error) + AddMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) + ChangeMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) + RemoveMailTemplate(ctx context.Context) error + + GetDefaultMailTexts(ctx context.Context) (*iam_model.MailTextsView, error) + GetMailTexts(ctx context.Context) (*iam_model.MailTextsView, error) + AddMailText(ctx context.Context, mailText *iam_model.MailText) (*iam_model.MailText, error) + ChangeMailText(ctx context.Context, mailText *iam_model.MailText) (*iam_model.MailText, error) + RemoveMailText(ctx context.Context, mailText *iam_model.MailText) error } diff --git a/internal/notification/repository/eventsourcing/handler/notification.go b/internal/notification/repository/eventsourcing/handler/notification.go index ac22f914cf..7d2b3534bd 100644 --- a/internal/notification/repository/eventsourcing/handler/notification.go +++ b/internal/notification/repository/eventsourcing/handler/notification.go @@ -4,7 +4,9 @@ import ( "context" "encoding/json" "github.com/caos/zitadel/internal/user/repository/view/model" + view_model "github.com/caos/zitadel/internal/user/repository/view/model" "github.com/caos/zitadel/internal/v2/command" + "golang.org/x/text/language" "net/http" "time" @@ -12,6 +14,7 @@ import ( "github.com/caos/zitadel/internal/api/authz" sd "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/crypto" + "github.com/caos/zitadel/internal/errors" caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/models" @@ -26,10 +29,19 @@ import ( ) const ( - notificationTable = "notification.notifications" - NotifyUserID = "NOTIFICATION" - labelPolicyTableOrg = "management.label_policies" - labelPolicyTableDef = "adminapi.label_policies" + notificationTable = "notification.notifications" + NotifyUserID = "NOTIFICATION" + labelPolicyTableOrg = "management.label_policies" + labelPolicyTableDef = "adminapi.label_policies" + mailTemplateTableOrg = "management.mail_templates" + mailTemplateTableDef = "adminapi.mail_templates" + mailTextTableOrg = "management.mail_texts" + mailTextTableDef = "adminapi.mail_texts" + mailTextTypeDomainClaimed = "DomainClaimed" + mailTextTypeInitCode = "InitCode" + mailTextTypePasswordReset = "PasswordReset" + mailTextTypeVerifyEmail = "VerifyEmail" + mailTextTypeVerifyPhone = "VerifyPhone" ) type Notification struct { @@ -84,8 +96,8 @@ func (_ *Notification) AggregateTypes() []models.AggregateType { return []models.AggregateType{es_model.UserAggregate} } -func (n *Notification) CurrentSequence(event *models.Event) (uint64, error) { - sequence, err := n.view.GetLatestNotificationSequence(string(event.AggregateType)) +func (n *Notification) CurrentSequence() (uint64, error) { + sequence, err := n.view.GetLatestNotificationSequence() if err != nil { return 0, err } @@ -93,7 +105,7 @@ func (n *Notification) CurrentSequence(event *models.Event) (uint64, error) { } func (n *Notification) EventQuery() (*models.SearchQuery, error) { - sequence, err := n.view.GetLatestNotificationSequence("") + sequence, err := n.view.GetLatestNotificationSequence() if err != nil { return nil, err } @@ -140,11 +152,22 @@ func (n *Notification) handleInitUserCode(event *models.Event) (err error) { return err } + template, err := n.getMailTemplate(context.Background()) + if err != nil { + return err + } + user, err := n.getUserByID(event.AggregateID) if err != nil { return err } - err = types.SendUserInitCode(n.statikDir, n.i18n, user, initCode, n.systemDefaults, n.AesCrypto, colors) + + text, err := n.getMailText(context.Background(), mailTextTypeInitCode, user.PreferredLanguage) + if err != nil { + return err + } + + err = types.SendUserInitCode(string(template.Template), text, user, initCode, n.systemDefaults, n.AesCrypto, colors) if err != nil { return err } @@ -168,11 +191,21 @@ func (n *Notification) handlePasswordCode(event *models.Event) (err error) { return err } + template, err := n.getMailTemplate(context.Background()) + if err != nil { + return err + } + user, err := n.getUserByID(event.AggregateID) if err != nil { return err } - err = types.SendPasswordCode(n.statikDir, n.i18n, user, pwCode, n.systemDefaults, n.AesCrypto, colors) + + text, err := n.getMailText(context.Background(), mailTextTypePasswordReset, user.PreferredLanguage) + if err != nil { + return err + } + err = types.SendPasswordCode(string(template.Template), text, user, pwCode, n.systemDefaults, n.AesCrypto, colors) if err != nil { return err } @@ -196,11 +229,22 @@ func (n *Notification) handleEmailVerificationCode(event *models.Event) (err err return err } + template, err := n.getMailTemplate(context.Background()) + if err != nil { + return err + } + user, err := n.getUserByID(event.AggregateID) if err != nil { return err } - err = types.SendEmailVerificationCode(n.statikDir, n.i18n, user, emailCode, n.systemDefaults, n.AesCrypto, colors) + + text, err := n.getMailText(context.Background(), mailTextTypeVerifyEmail, user.PreferredLanguage) + if err != nil { + return err + } + + err = types.SendEmailVerificationCode(string(template.Template), text, user, emailCode, n.systemDefaults, n.AesCrypto, colors) if err != nil { return err } @@ -243,7 +287,21 @@ func (n *Notification) handleDomainClaimed(event *models.Event) (err error) { if err != nil { return err } - err = types.SendDomainClaimed(n.statikDir, n.i18n, user, data["userName"], n.systemDefaults) + colors, err := n.getLabelPolicy(context.Background()) + if err != nil { + return err + } + + template, err := n.getMailTemplate(context.Background()) + if err != nil { + return err + } + + text, err := n.getMailText(context.Background(), mailTextTypeDomainClaimed, user.PreferredLanguage) + if err != nil { + return err + } + err = types.SendDomainClaimed(string(template.Template), text, user, data["userName"], n.systemDefaults, colors) if err != nil { return err } @@ -312,13 +370,54 @@ func (n *Notification) getLabelPolicy(ctx context.Context) (*iam_model.LabelPoli return iam_es_model.LabelPolicyViewToModel(policy), err } -func (n *Notification) getUserByID(userID string) (*model.NotifyUser, error) { +// Read organization specific template +func (n *Notification) getMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error) { + // read from Org + template, err := n.view.MailTemplateByAggregateID(authz.GetCtxData(ctx).OrgID, mailTemplateTableOrg) + if errors.IsNotFound(err) { + // read from default + template, err = n.view.MailTemplateByAggregateID(n.systemDefaults.IamID, mailTemplateTableDef) + if err != nil { + return nil, err + } + template.Default = true + } + if err != nil { + return nil, err + } + return iam_es_model.MailTemplateViewToModel(template), err +} + +// Read organization specific texts +func (n *Notification) getMailText(ctx context.Context, textType string, lang string) (*iam_model.MailTextView, error) { + langTag := language.Make(lang) + if langTag == language.Und { + langTag = n.systemDefaults.DefaultLanguage + } + base, _ := langTag.Base() + // read from Org + mailText, err := n.view.MailTextByIDs(authz.GetCtxData(ctx).OrgID, textType, base.String(), mailTextTableOrg) + if errors.IsNotFound(err) { + // read from default + mailText, err = n.view.MailTextByIDs(n.systemDefaults.IamID, textType, base.String(), mailTextTableDef) + if err != nil { + return nil, err + } + mailText.Default = true + } + if err != nil { + return nil, err + } + return iam_es_model.MailTextViewToModel(mailText), err +} + +func (n *Notification) getUserByID(userID string) (*view_model.NotifyUser, error) { user, usrErr := n.view.NotifyUserByID(userID) if usrErr != nil && !caos_errs.IsNotFound(usrErr) { return nil, usrErr } if user == nil { - user = &model.NotifyUser{} + user = &view_model.NotifyUser{} } events, err := n.getUserEvents(userID, user.Sequence) if err != nil { @@ -331,7 +430,7 @@ func (n *Notification) getUserByID(userID string) (*model.NotifyUser, error) { } } if userCopy.State == int32(model.UserStateDeleted) { - return nil, caos_errs.ThrowNotFound(nil, "EVENT-3n8fs", "Errors.User.NotFound") + return nil, caos_errs.ThrowNotFound(nil, "HANDLER-3n8fs", "Errors.User.NotFound") } return &userCopy, nil } diff --git a/internal/notification/repository/eventsourcing/handler/notify_user.go b/internal/notification/repository/eventsourcing/handler/notify_user.go index 4b82a16c0c..7d774d19ea 100644 --- a/internal/notification/repository/eventsourcing/handler/notify_user.go +++ b/internal/notification/repository/eventsourcing/handler/notify_user.go @@ -63,8 +63,8 @@ func (_ *NotifyUser) AggregateTypes() []es_models.AggregateType { return []es_models.AggregateType{es_model.UserAggregate, org_es_model.OrgAggregate} } -func (p *NotifyUser) CurrentSequence(event *es_models.Event) (uint64, error) { - sequence, err := p.view.GetLatestNotifyUserSequence(string(event.AggregateType)) +func (p *NotifyUser) CurrentSequence() (uint64, error) { + sequence, err := p.view.GetLatestNotifyUserSequence() if err != nil { return 0, err } @@ -72,7 +72,7 @@ func (p *NotifyUser) CurrentSequence(event *es_models.Event) (uint64, error) { } func (p *NotifyUser) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := p.view.GetLatestNotifyUserSequence("") + sequence, err := p.view.GetLatestNotifyUserSequence() if err != nil { return nil, err } diff --git a/internal/notification/repository/eventsourcing/view/mail_template.go b/internal/notification/repository/eventsourcing/view/mail_template.go new file mode 100644 index 0000000000..0e1ddf8941 --- /dev/null +++ b/internal/notification/repository/eventsourcing/view/mail_template.go @@ -0,0 +1,10 @@ +package view + +import ( + "github.com/caos/zitadel/internal/iam/repository/view" + "github.com/caos/zitadel/internal/iam/repository/view/model" +) + +func (v *View) MailTemplateByAggregateID(aggregateID string, mailTemplateTableVar string) (*model.MailTemplateView, error) { + return view.GetMailTemplateByAggregateID(v.Db, mailTemplateTableVar, aggregateID) +} diff --git a/internal/notification/repository/eventsourcing/view/mail_text.go b/internal/notification/repository/eventsourcing/view/mail_text.go new file mode 100644 index 0000000000..3413b73455 --- /dev/null +++ b/internal/notification/repository/eventsourcing/view/mail_text.go @@ -0,0 +1,10 @@ +package view + +import ( + "github.com/caos/zitadel/internal/iam/repository/view" + "github.com/caos/zitadel/internal/iam/repository/view/model" +) + +func (v *View) MailTextByIDs(aggregateID string, textType string, language string, mailTextTableVar string) (*model.MailTextView, error) { + return view.GetMailTextByIDs(v.Db, mailTextTableVar, aggregateID, textType, language) +} diff --git a/internal/notification/repository/eventsourcing/view/notification.go b/internal/notification/repository/eventsourcing/view/notification.go index b14242f47e..fc7041bbab 100644 --- a/internal/notification/repository/eventsourcing/view/notification.go +++ b/internal/notification/repository/eventsourcing/view/notification.go @@ -9,8 +9,8 @@ const ( notificationTable = "notification.notifications" ) -func (v *View) GetLatestNotificationSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(notificationTable, aggregateType) +func (v *View) GetLatestNotificationSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(notificationTable) } func (v *View) ProcessedNotificationSequence(event *models.Event) error { diff --git a/internal/notification/repository/eventsourcing/view/notify_user.go b/internal/notification/repository/eventsourcing/view/notify_user.go index f81c986d0a..b3b3397f77 100644 --- a/internal/notification/repository/eventsourcing/view/notify_user.go +++ b/internal/notification/repository/eventsourcing/view/notify_user.go @@ -36,8 +36,8 @@ func (v *View) DeleteNotifyUser(userID string, event *models.Event) error { return v.ProcessedNotifyUserSequence(event) } -func (v *View) GetLatestNotifyUserSequence(aggregateType string) (*repository.CurrentSequence, error) { - return v.latestSequence(notifyUserTable, aggregateType) +func (v *View) GetLatestNotifyUserSequence() (*repository.CurrentSequence, error) { + return v.latestSequence(notifyUserTable) } func (v *View) ProcessedNotifyUserSequence(event *models.Event) error { diff --git a/internal/notification/repository/eventsourcing/view/sequence.go b/internal/notification/repository/eventsourcing/view/sequence.go index 8d56cc19b9..d7155c6292 100644 --- a/internal/notification/repository/eventsourcing/view/sequence.go +++ b/internal/notification/repository/eventsourcing/view/sequence.go @@ -12,15 +12,15 @@ const ( ) func (v *View) saveCurrentSequence(viewName string, event *models.Event) error { - return repository.SaveCurrentSequence(v.Db, sequencesTable, viewName, string(event.AggregateType), event.Sequence, event.CreationDate) + return repository.SaveCurrentSequence(v.Db, sequencesTable, viewName, event.Sequence, event.CreationDate) } -func (v *View) latestSequence(viewName, aggregateType string) (*repository.CurrentSequence, error) { - return repository.LatestSequence(v.Db, sequencesTable, viewName, aggregateType) +func (v *View) latestSequence(viewName string) (*repository.CurrentSequence, error) { + return repository.LatestSequence(v.Db, sequencesTable, viewName) } func (v *View) updateSpoolerRunSequence(viewName string) error { - currentSequence, err := repository.LatestSequence(v.Db, sequencesTable, viewName, "") + currentSequence, err := repository.LatestSequence(v.Db, sequencesTable, viewName) if err != nil { return err } diff --git a/internal/notification/templates/template.go b/internal/notification/templates/template.go index ae0dd70c38..98209366c2 100644 --- a/internal/notification/templates/template.go +++ b/internal/notification/templates/template.go @@ -12,23 +12,21 @@ const ( templateFileName = "template.html" ) -func GetParsedTemplate(dir http.FileSystem, contentData interface{}) (string, error) { - template, err := ParseTemplateFile(dir, "", contentData) +func GetParsedTemplate(mailhtml string, contentData interface{}) (string, error) { + template, err := ParseTemplateFile(mailhtml, contentData) if err != nil { return "", err } return ParseTemplateText(template, contentData) } -func ParseTemplateFile(dir http.FileSystem, fileName string, data interface{}) (string, error) { - if fileName == "" { - fileName = templateFileName - } - template, err := readFile(dir, fileName) +func ParseTemplateFile(mailhtml string, data interface{}) (string, error) { + tmpl, err := template.New("tmpl").Parse(mailhtml) if err != nil { return "", err } - return parseTemplate(template, data) + + return parseTemplate(tmpl, data) } func ParseTemplateText(text string, data interface{}) (string, error) { @@ -63,3 +61,20 @@ func readFile(dir http.FileSystem, fileName string) (*template.Template, error) } return tmpl, nil } + +func readFileFromDatabase(dir http.FileSystem, fileName string) (*template.Template, error) { + f, err := dir.Open(templatesPath + "/" + fileName) + if err != nil { + return nil, err + } + defer f.Close() + content, err := ioutil.ReadAll(f) + if err != nil { + return nil, err + } + tmpl, err := template.New(fileName).Parse(string(content)) + if err != nil { + return nil, err + } + return tmpl, nil +} diff --git a/internal/notification/types/domain_claimed.go b/internal/notification/types/domain_claimed.go index d89dbcc0fd..5af796f735 100644 --- a/internal/notification/types/domain_claimed.go +++ b/internal/notification/types/domain_claimed.go @@ -1,11 +1,11 @@ package types import ( - "net/http" + "html" "strings" "github.com/caos/zitadel/internal/config/systemdefaults" - "github.com/caos/zitadel/internal/i18n" + iam_model "github.com/caos/zitadel/internal/iam/model" "github.com/caos/zitadel/internal/notification/templates" view_model "github.com/caos/zitadel/internal/user/repository/view/model" ) @@ -15,7 +15,7 @@ type DomainClaimedData struct { URL string } -func SendDomainClaimed(dir http.FileSystem, i18n *i18n.Translator, user *view_model.NotifyUser, username string, systemDefaults systemdefaults.SystemDefaults) error { +func SendDomainClaimed(mailhtml string, text *iam_model.MailTextView, user *view_model.NotifyUser, username string, systemDefaults systemdefaults.SystemDefaults, colors *iam_model.LabelPolicyView) error { url, err := templates.ParseTemplateText(systemDefaults.Notifications.Endpoints.DomainClaimed, &UrlData{UserID: user.ID}) if err != nil { return err @@ -27,11 +27,28 @@ func SendDomainClaimed(dir http.FileSystem, i18n *i18n.Translator, user *view_mo "TempUsername": username, "Domain": strings.Split(user.LastEmail, "@")[1], } - systemDefaults.Notifications.TemplateData.DomainClaimed.Translate(i18n, args, user.PreferredLanguage) - data := &DomainClaimedData{TemplateData: systemDefaults.Notifications.TemplateData.DomainClaimed, URL: url} - template, err := templates.GetParsedTemplate(dir, data) + + text.Greeting, err = templates.ParseTemplateText(text.Greeting, args) + text.Text, err = templates.ParseTemplateText(text.Text, args) + text.Text = html.UnescapeString(text.Text) + + emailCodeData := &DomainClaimedData{ + TemplateData: templates.TemplateData{ + Title: text.Title, + PreHeader: text.PreHeader, + Subject: text.Subject, + Greeting: text.Greeting, + Text: html.UnescapeString(text.Text), + Href: url, + ButtonText: text.ButtonText, + PrimaryColor: colors.PrimaryColor, + SecondaryColor: colors.SecondaryColor, + }, + URL: url, + } + template, err := templates.GetParsedTemplate(mailhtml, emailCodeData) if err != nil { return err } - return generateEmail(user, systemDefaults.Notifications.TemplateData.DomainClaimed.Subject, template, systemDefaults.Notifications, true) + return generateEmail(user, text.Subject, template, systemDefaults.Notifications, true) } diff --git a/internal/notification/types/email_verification_code.go b/internal/notification/types/email_verification_code.go index 77f5750e48..8c97af995b 100644 --- a/internal/notification/types/email_verification_code.go +++ b/internal/notification/types/email_verification_code.go @@ -1,11 +1,10 @@ package types import ( - "net/http" + "html" "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/crypto" - "github.com/caos/zitadel/internal/i18n" iam_model "github.com/caos/zitadel/internal/iam/model" "github.com/caos/zitadel/internal/notification/templates" es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" @@ -17,7 +16,7 @@ type EmailVerificationCodeData struct { URL string } -func SendEmailVerificationCode(dir http.FileSystem, i18n *i18n.Translator, user *view_model.NotifyUser, code *es_model.EmailCode, systemDefaults systemdefaults.SystemDefaults, alg crypto.EncryptionAlgorithm, colors *iam_model.LabelPolicyView) error { +func SendEmailVerificationCode(mailhtml string, text *iam_model.MailTextView, user *view_model.NotifyUser, code *es_model.EmailCode, systemDefaults systemdefaults.SystemDefaults, alg crypto.EncryptionAlgorithm, colors *iam_model.LabelPolicyView) error { codeString, err := crypto.DecryptString(code.Code, alg) if err != nil { return err @@ -31,15 +30,29 @@ func SendEmailVerificationCode(dir http.FileSystem, i18n *i18n.Translator, user "LastName": user.LastName, "Code": codeString, } - systemDefaults.Notifications.TemplateData.VerifyEmail.Translate(i18n, args, user.PreferredLanguage) - emailCodeData := &EmailVerificationCodeData{TemplateData: systemDefaults.Notifications.TemplateData.VerifyEmail, URL: url} - // Set the color in initCodeData - emailCodeData.PrimaryColor = colors.PrimaryColor - emailCodeData.SecondaryColor = colors.SecondaryColor - template, err := templates.GetParsedTemplate(dir, emailCodeData) + text.Greeting, err = templates.ParseTemplateText(text.Greeting, args) + text.Text, err = templates.ParseTemplateText(text.Text, args) + text.Text = html.UnescapeString(text.Text) + + emailCodeData := &EmailVerificationCodeData{ + TemplateData: templates.TemplateData{ + Title: text.Title, + PreHeader: text.PreHeader, + Subject: text.Subject, + Greeting: text.Greeting, + Text: html.UnescapeString(text.Text), + Href: url, + ButtonText: text.ButtonText, + PrimaryColor: colors.PrimaryColor, + SecondaryColor: colors.SecondaryColor, + }, + URL: url, + } + + template, err := templates.GetParsedTemplate(mailhtml, emailCodeData) if err != nil { return err } - return generateEmail(user, systemDefaults.Notifications.TemplateData.VerifyEmail.Subject, template, systemDefaults.Notifications, true) + return generateEmail(user, text.Subject, template, systemDefaults.Notifications, true) } diff --git a/internal/notification/types/init_code.go b/internal/notification/types/init_code.go index 86da8d3ccd..c403e1bdb4 100644 --- a/internal/notification/types/init_code.go +++ b/internal/notification/types/init_code.go @@ -1,11 +1,10 @@ package types import ( - "net/http" + "html" "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/crypto" - "github.com/caos/zitadel/internal/i18n" iam_model "github.com/caos/zitadel/internal/iam/model" "github.com/caos/zitadel/internal/notification/templates" es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" @@ -23,7 +22,7 @@ type UrlData struct { PasswordSet bool } -func SendUserInitCode(dir http.FileSystem, i18n *i18n.Translator, user *view_model.NotifyUser, code *es_model.InitUserCode, systemDefaults systemdefaults.SystemDefaults, alg crypto.EncryptionAlgorithm, colors *iam_model.LabelPolicyView) error { +func SendUserInitCode(mailhtml string, text *iam_model.MailTextView, user *view_model.NotifyUser, code *es_model.InitUserCode, systemDefaults systemdefaults.SystemDefaults, alg crypto.EncryptionAlgorithm, colors *iam_model.LabelPolicyView) error { codeString, err := crypto.DecryptString(code.Code, alg) if err != nil { return err @@ -38,15 +37,28 @@ func SendUserInitCode(dir http.FileSystem, i18n *i18n.Translator, user *view_mod "Code": codeString, "PreferredLoginName": user.PreferredLoginName, } - systemDefaults.Notifications.TemplateData.InitCode.Translate(i18n, args, user.PreferredLanguage) - initCodeData := &InitCodeEmailData{TemplateData: systemDefaults.Notifications.TemplateData.InitCode, URL: url} - // Set the color in initCodeData - initCodeData.PrimaryColor = colors.PrimaryColor - initCodeData.SecondaryColor = colors.SecondaryColor - template, err := templates.GetParsedTemplate(dir, initCodeData) + text.Greeting, err = templates.ParseTemplateText(text.Greeting, args) + text.Text, err = templates.ParseTemplateText(text.Text, args) + text.Text = html.UnescapeString(text.Text) + + emailCodeData := &InitCodeEmailData{ + TemplateData: templates.TemplateData{ + Title: text.Title, + PreHeader: text.PreHeader, + Subject: text.Subject, + Greeting: text.Greeting, + Text: html.UnescapeString(text.Text), + Href: url, + ButtonText: text.ButtonText, + PrimaryColor: colors.PrimaryColor, + SecondaryColor: colors.SecondaryColor, + }, + URL: url, + } + template, err := templates.GetParsedTemplate(mailhtml, emailCodeData) if err != nil { return err } - return generateEmail(user, systemDefaults.Notifications.TemplateData.InitCode.Subject, template, systemDefaults.Notifications, true) + return generateEmail(user, text.Subject, template, systemDefaults.Notifications, true) } diff --git a/internal/notification/types/password_code.go b/internal/notification/types/password_code.go index 41f6a21dc6..7f072d5c03 100644 --- a/internal/notification/types/password_code.go +++ b/internal/notification/types/password_code.go @@ -1,11 +1,10 @@ package types import ( - "net/http" + "html" "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/crypto" - "github.com/caos/zitadel/internal/i18n" iam_model "github.com/caos/zitadel/internal/iam/model" "github.com/caos/zitadel/internal/notification/templates" es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" @@ -19,7 +18,7 @@ type PasswordCodeData struct { URL string } -func SendPasswordCode(dir http.FileSystem, i18n *i18n.Translator, user *view_model.NotifyUser, code *es_model.PasswordCode, systemDefaults systemdefaults.SystemDefaults, alg crypto.EncryptionAlgorithm, colors *iam_model.LabelPolicyView) error { +func SendPasswordCode(mailhtml string, text *iam_model.MailTextView, user *view_model.NotifyUser, code *es_model.PasswordCode, systemDefaults systemdefaults.SystemDefaults, alg crypto.EncryptionAlgorithm, colors *iam_model.LabelPolicyView) error { codeString, err := crypto.DecryptString(code.Code, alg) if err != nil { return err @@ -33,15 +32,30 @@ func SendPasswordCode(dir http.FileSystem, i18n *i18n.Translator, user *view_mod "LastName": user.LastName, "Code": codeString, } - systemDefaults.Notifications.TemplateData.PasswordReset.Translate(i18n, args, user.PreferredLanguage) - passwordCodeData := &PasswordCodeData{TemplateData: systemDefaults.Notifications.TemplateData.PasswordReset, FirstName: user.FirstName, LastName: user.LastName, URL: url} - // Set the color in initCodeData - passwordCodeData.PrimaryColor = colors.PrimaryColor - passwordCodeData.SecondaryColor = colors.SecondaryColor - template, err := templates.GetParsedTemplate(dir, passwordCodeData) + text.Greeting, err = templates.ParseTemplateText(text.Greeting, args) + text.Text, err = templates.ParseTemplateText(text.Text, args) + text.Text = html.UnescapeString(text.Text) + + emailCodeData := &PasswordCodeData{ + TemplateData: templates.TemplateData{ + Title: text.Title, + PreHeader: text.PreHeader, + Subject: text.Subject, + Greeting: text.Greeting, + Text: html.UnescapeString(text.Text), + Href: url, + ButtonText: text.ButtonText, + PrimaryColor: colors.PrimaryColor, + SecondaryColor: colors.SecondaryColor, + }, + FirstName: user.FirstName, + LastName: user.LastName, + URL: url, + } + template, err := templates.GetParsedTemplate(mailhtml, emailCodeData) if err != nil { return err } - return generateEmail(user, systemDefaults.Notifications.TemplateData.PasswordReset.Subject, template, systemDefaults.Notifications, false) + return generateEmail(user, text.Subject, template, systemDefaults.Notifications, true) } diff --git a/internal/org/model/org.go b/internal/org/model/org.go index 3a0bdec40e..6ae649acd4 100644 --- a/internal/org/model/org.go +++ b/internal/org/model/org.go @@ -19,6 +19,8 @@ type Org struct { OrgIamPolicy *iam_model.OrgIAMPolicy LoginPolicy *iam_model.LoginPolicy LabelPolicy *iam_model.LabelPolicy + MailTemplate *iam_model.MailTemplate + MailTexts []*iam_model.MailText PasswordComplexityPolicy *iam_model.PasswordComplexityPolicy PasswordAgePolicy *iam_model.PasswordAgePolicy PasswordLockoutPolicy *iam_model.PasswordLockoutPolicy diff --git a/internal/org/repository/eventsourcing/eventstore.go b/internal/org/repository/eventsourcing/eventstore.go index dff8a95b22..8266c27a0b 100644 --- a/internal/org/repository/eventsourcing/eventstore.go +++ b/internal/org/repository/eventsourcing/eventstore.go @@ -1153,3 +1153,121 @@ func (es *OrgEventstore) RemovePasswordLockoutPolicy(ctx context.Context, policy addAggregate := PasswordLockoutPolicyRemovedAggregate(es.Eventstore.AggregateCreator(), repoOrg) return es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) } + +func (es *OrgEventstore) AddMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) { + if template == nil || !template.IsValid() { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-nb66d", "Errors.Org.MailTemplateInvalid") + } + org, err := es.OrgByID(ctx, org_model.NewOrg(template.AggregateID)) + if err != nil { + return nil, err + } + + repoOrg := model.OrgFromModel(org) + repoMailTemplate := iam_es_model.MailTemplateFromModel(template) + + addAggregate := MailTemplateAddedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoMailTemplate) + err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) + if err != nil { + return nil, err + } + return iam_es_model.MailTemplateToModel(repoOrg.MailTemplate), nil +} + +func (es *OrgEventstore) ChangeMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) { + if template == nil || !template.IsValid() { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-FV2qE", "Errors.Org.MailTemplateInvalid") + } + org, err := es.OrgByID(ctx, org_model.NewOrg(template.AggregateID)) + if err != nil { + return nil, err + } + + repoOrg := model.OrgFromModel(org) + repoMailTemplate := iam_es_model.MailTemplateFromModel(template) + + addAggregate := MailTemplateChangedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoMailTemplate) + err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) + if err != nil { + return nil, err + } + repoOrg.MailTemplate.Template = repoMailTemplate.Template + return iam_es_model.MailTemplateToModel(repoOrg.MailTemplate), nil +} + +func (es *OrgEventstore) RemoveMailTemplate(ctx context.Context, template *iam_model.MailTemplate) error { + if template == nil || !template.IsValid() { + return errors.ThrowPreconditionFailed(nil, "EVENT-LulaW", "Errors.Org.MailTemplate.Invalid") + } + org, err := es.OrgByID(ctx, org_model.NewOrg(template.AggregateID)) + if err != nil { + return err + } + repoOrg := model.OrgFromModel(org) + + addAggregate := MailTemplateRemovedAggregate(es.Eventstore.AggregateCreator(), repoOrg) + return es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) +} + +func (es *OrgEventstore) AddMailText(ctx context.Context, mailtext *iam_model.MailText) (*iam_model.MailText, error) { + if mailtext == nil || !mailtext.IsValid() { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-108Iz", "Errors.Org.MailTextInvalid") + } + org, err := es.OrgByID(ctx, org_model.NewOrg(mailtext.AggregateID)) + if err != nil { + return nil, err + } + + repoOrg := model.OrgFromModel(org) + repoMailText := iam_es_model.MailTextFromModel(mailtext) + + addAggregate := MailTextAddedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoMailText) + err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) + if err != nil { + return nil, err + } + + if _, r := iam_es_model.GetMailText(repoOrg.MailTexts, repoMailText.MailTextType, repoMailText.Language); r != nil { + return iam_es_model.MailTextToModel(r), nil + } + return nil, errors.ThrowInternal(nil, "EVENT-oc1GN", "Errors.Internal") +} + +func (es *OrgEventstore) ChangeMailText(ctx context.Context, mailtext *iam_model.MailText) (*iam_model.MailText, error) { + if mailtext == nil || !mailtext.IsValid() { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-fdbqE", "Errors.Org.MailTextInvalid") + } + org, err := es.OrgByID(ctx, org_model.NewOrg(mailtext.AggregateID)) + if err != nil { + return nil, err + } + + repoOrg := model.OrgFromModel(org) + repoMailText := iam_es_model.MailTextFromModel(mailtext) + + addAggregate := MailTextChangedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoMailText) + err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) + if err != nil { + return nil, err + } + + if _, r := iam_es_model.GetMailText(repoOrg.MailTexts, mailtext.MailTextType, mailtext.Language); r != nil { + return iam_es_model.MailTextToModel(r), nil + } + return nil, errors.ThrowInternal(nil, "EVENT-F2whI", "Errors.Internal") +} + +func (es *OrgEventstore) RemoveMailText(ctx context.Context, mailtext *iam_model.MailText) error { + if mailtext == nil || !mailtext.IsValid() { + return errors.ThrowPreconditionFailed(nil, "EVENT-LulaW", "Errors.Org.MailText.Invalid") + } + org, err := es.OrgByID(ctx, org_model.NewOrg(mailtext.AggregateID)) + if err != nil { + return err + } + repoOrg := model.OrgFromModel(org) + repoMailText := iam_es_model.MailTextFromModel(mailtext) + + addAggregate := MailTextRemovedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoMailText) + return es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) +} diff --git a/internal/org/repository/eventsourcing/eventstore_mock_test.go b/internal/org/repository/eventsourcing/eventstore_mock_test.go index f36f48d7f9..8ca15230c1 100644 --- a/internal/org/repository/eventsourcing/eventstore_mock_test.go +++ b/internal/org/repository/eventsourcing/eventstore_mock_test.go @@ -192,3 +192,31 @@ func GetMockChangesOrgWithLabelPolicy(ctrl *gomock.Controller) *OrgEventstore { mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) return GetMockedEventstore(ctrl, mockEs) } + +func GetMockChangesOrgWithMailTemplate(ctrl *gomock.Controller) *OrgEventstore { + orgData, _ := json.Marshal(model.Org{Name: "MusterOrg"}) + mailTemplate, _ := json.Marshal(iam_es_model.MailTemplate{Template: []byte("")}) + events := []*es_models.Event{ + &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.OrgAdded, Data: orgData}, + &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.MailTemplateAdded, Data: mailTemplate}, + } + mockEs := mock.NewMockEventstore(ctrl) + mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) + mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) + mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) + return GetMockedEventstore(ctrl, mockEs) +} + +func GetMockChangesOrgWithMailText(ctrl *gomock.Controller) *OrgEventstore { + orgData, _ := json.Marshal(model.Org{Name: "MusterOrg"}) + mailText, _ := json.Marshal(iam_es_model.MailText{MailTextType: "Type", Language: "DE"}) + events := []*es_models.Event{ + &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.OrgAdded, Data: orgData}, + &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.MailTextAdded, Data: mailText}, + } + mockEs := mock.NewMockEventstore(ctrl) + mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) + mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) + mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) + return GetMockedEventstore(ctrl, mockEs) +} diff --git a/internal/org/repository/eventsourcing/eventstore_test.go b/internal/org/repository/eventsourcing/eventstore_test.go index b1b0a75aa3..4db2c10943 100644 --- a/internal/org/repository/eventsourcing/eventstore_test.go +++ b/internal/org/repository/eventsourcing/eventstore_test.go @@ -3996,3 +3996,327 @@ func TestRemovePasswordLockoutPolicy(t *testing.T) { }) } } + +func TestAddMailTemplate(t *testing.T) { + ctrl := gomock.NewController(t) + type args struct { + es *OrgEventstore + ctx context.Context + template *iam_model.MailTemplate + } + type res struct { + result *iam_model.MailTemplate + wantErr bool + errFunc func(err error) bool + } + tests := []struct { + name string + args args + res res + }{ + { + name: "add label template, ok", + args: args{ + es: GetMockChangesOrgOK(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + template: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + Template: []byte(""), + }, + }, + res: res{ + result: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + Template: []byte(""), + }, + }, + }, + { + name: "invalid template", + args: args{ + es: GetMockChangesOrgOK(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + template: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + { + name: "existing org not found", + args: args{ + es: GetMockChangesOrgNoEvents(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + template: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsNotFound, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := tt.args.es.AddMailTemplate(tt.args.ctx, tt.args.template) + if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { + t.Errorf("got wrong err: %v ", err) + return + } + if tt.res.wantErr && tt.res.errFunc(err) { + return + } + if string(result.Template) != string(tt.res.result.Template) { + t.Errorf("got wrong result Template: expected: %v, actual: %v ", tt.res.result.Template, result.Template) + } + }) + } +} + +func TestChangeMailTemplate(t *testing.T) { + ctrl := gomock.NewController(t) + type args struct { + es *OrgEventstore + ctx context.Context + template *iam_model.MailTemplate + } + type res struct { + result *iam_model.MailTemplate + wantErr bool + errFunc func(err error) bool + } + tests := []struct { + name string + args args + res res + }{ + { + name: "add mail template, ok", + args: args{ + es: GetMockChangesOrgWithMailTemplate(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + template: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + Template: []byte(""), + }, + }, + res: res{ + result: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + Template: []byte(""), + }, + }, + }, + { + name: "invalid template", + args: args{ + es: GetMockChangesOrgOK(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + template: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + { + name: "existing iam not found", + args: args{ + es: GetMockChangesOrgNoEvents(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + template: &iam_model.MailTemplate{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsNotFound, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := tt.args.es.ChangeMailTemplate(tt.args.ctx, tt.args.template) + if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { + t.Errorf("got wrong err: %v ", err) + return + } + if tt.res.wantErr && tt.res.errFunc(err) { + return + } + if string(result.Template) != string(tt.res.result.Template) { + t.Errorf("got wrong result Template: expected: %v, actual: %v ", tt.res.result.Template, result.Template) + } + }) + } +} + +func TestAddMailText(t *testing.T) { + ctrl := gomock.NewController(t) + type args struct { + es *OrgEventstore + ctx context.Context + mailtext *iam_model.MailText + } + type res struct { + result *iam_model.MailText + wantErr bool + errFunc func(err error) bool + } + tests := []struct { + name string + args args + res res + }{ + { + name: "add label mailtext, ok", + args: args{ + es: GetMockChangesOrgOK(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + mailtext: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + MailTextType: "Type", + Language: "DE", + }, + }, + res: res{ + result: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + MailTextType: "Type", + Language: "DE", + }, + }, + }, + { + name: "invalid mailtext", + args: args{ + es: GetMockChangesOrgOK(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + mailtext: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + { + name: "existing org not found", + args: args{ + es: GetMockChangesOrgNoEvents(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + mailtext: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsNotFound, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := tt.args.es.AddMailText(tt.args.ctx, tt.args.mailtext) + if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { + t.Errorf("got wrong err: %v ", err) + return + } + if tt.res.wantErr && tt.res.errFunc(err) { + return + } + if result.MailTextType != tt.res.result.MailTextType { + t.Errorf("got wrong result MailTextType: expected: %v, actual: %v ", tt.res.result.MailTextType, result.MailTextType) + } + }) + } +} + +func TestChangeMailText(t *testing.T) { + ctrl := gomock.NewController(t) + type args struct { + es *OrgEventstore + ctx context.Context + mailtext *iam_model.MailText + } + type res struct { + result *iam_model.MailText + wantErr bool + errFunc func(err error) bool + } + tests := []struct { + name string + args args + res res + }{ + { + name: "add label mailtext, ok", + args: args{ + es: GetMockChangesOrgWithMailText(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + mailtext: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + MailTextType: "Type", + Language: "DE", + }, + }, + res: res{ + result: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + MailTextType: "Type", + Language: "DE", + }, + }, + }, + { + name: "invalid mailtext", + args: args{ + es: GetMockChangesOrgOK(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + mailtext: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + { + name: "existing iam not found", + args: args{ + es: GetMockChangesOrgNoEvents(ctrl), + ctx: authz.NewMockContext("orgID", "userID"), + mailtext: &iam_model.MailText{ + ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, + }, + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsNotFound, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := tt.args.es.ChangeMailText(tt.args.ctx, tt.args.mailtext) + if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { + t.Errorf("got wrong err: %v ", err) + return + } + if tt.res.wantErr && tt.res.errFunc(err) { + return + } + if string(result.MailTextType) != string(tt.res.result.MailTextType) { + t.Errorf("got wrong result MailTextType: expected: %v, actual: %v ", tt.res.result.MailTextType, result.MailTextType) + } + }) + } +} diff --git a/internal/org/repository/eventsourcing/label_policy_test.go b/internal/org/repository/eventsourcing/label_policy_test.go index ccd0c2a6ec..9be177f664 100644 --- a/internal/org/repository/eventsourcing/label_policy_test.go +++ b/internal/org/repository/eventsourcing/label_policy_test.go @@ -30,7 +30,7 @@ func TestLabelPolicyAddedAggregate(t *testing.T) { res res }{ { - name: "add label polciy", + name: "add label policy", args: args{ ctx: authz.NewMockContext("orgID", "userID"), existing: &model.Org{ diff --git a/internal/org/repository/eventsourcing/mail_template.go b/internal/org/repository/eventsourcing/mail_template.go new file mode 100644 index 0000000000..f185b1c07d --- /dev/null +++ b/internal/org/repository/eventsourcing/mail_template.go @@ -0,0 +1,77 @@ +package eventsourcing + +import ( + "context" + + "github.com/caos/zitadel/internal/errors" + es_models "github.com/caos/zitadel/internal/eventstore/models" + iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" + "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" +) + +func MailTemplateAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, policy *iam_es_model.MailTemplate) func(ctx context.Context) (*es_models.Aggregate, error) { + return func(ctx context.Context) (*es_models.Aggregate, error) { + if policy == nil { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-4BeRi", "Errors.Internal") + } + agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) + if err != nil { + return nil, err + } + validationQuery := es_models.NewSearchQuery(). + AggregateTypeFilter(model.OrgAggregate). + AggregateIDFilter(existing.AggregateID) + + validation := checkExistingMailTemplateValidation() + agg.SetPrecondition(validationQuery, validation) + return agg.AppendEvent(model.MailTemplateAdded, policy) + } +} + +func MailTemplateChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, template *iam_es_model.MailTemplate) func(ctx context.Context) (*es_models.Aggregate, error) { + return func(ctx context.Context) (*es_models.Aggregate, error) { + if template == nil { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-yzXO0", "Errors.Internal") + } + agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) + if err != nil { + return nil, err + } + changes := existing.MailTemplate.Changes(template) + if len(changes) == 0 { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-erTCI", "Errors.NoChangesFound") + } + return agg.AppendEvent(model.MailTemplateChanged, changes) + } +} + +func MailTemplateRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org) func(ctx context.Context) (*es_models.Aggregate, error) { + return func(ctx context.Context) (*es_models.Aggregate, error) { + if existing == nil { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-2jVit", "Errors.Internal") + } + agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) + if err != nil { + return nil, err + } + return agg.AppendEvent(model.MailTemplateRemoved, nil) + } +} + +func checkExistingMailTemplateValidation() func(...*es_models.Event) error { + return func(events ...*es_models.Event) error { + existing := false + for _, event := range events { + switch event.Type { + case model.MailTemplateAdded: + existing = true + case model.MailTemplateRemoved: + existing = false + } + } + if existing { + return errors.ThrowPreconditionFailed(nil, "EVENT-aUH4D", "Errors.Org.MailTemplate.AlreadyExists") + } + return nil + } +} diff --git a/internal/org/repository/eventsourcing/mail_template_test.go b/internal/org/repository/eventsourcing/mail_template_test.go new file mode 100644 index 0000000000..bd2b10ce06 --- /dev/null +++ b/internal/org/repository/eventsourcing/mail_template_test.go @@ -0,0 +1,185 @@ +package eventsourcing + +import ( + "context" + "testing" + + "github.com/caos/zitadel/internal/api/authz" + caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/models" + iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" + "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" +) + +func TestMailTemplateAddedAggregate(t *testing.T) { + type args struct { + ctx context.Context + existing *model.Org + new *iam_es_model.MailTemplate + aggCreator *models.AggregateCreator + } + type res struct { + eventLen int + eventTypes []models.EventType + wantErr bool + errFunc func(err error) bool + } + tests := []struct { + name string + args args + res res + }{ + { + name: "add mailtemplate", + args: args{ + ctx: authz.NewMockContext("orgID", "userID"), + existing: &model.Org{ + ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, + }, + new: &iam_es_model.MailTemplate{ + ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, + Template: []byte(""), + }, + aggCreator: models.NewAggregateCreator("Test"), + }, + res: res{ + eventLen: 1, + eventTypes: []models.EventType{model.MailTemplateAdded}, + }, + }, + { + name: "existing org nil", + args: args{ + ctx: authz.NewMockContext("orgID", "userID"), + existing: nil, + aggCreator: models.NewAggregateCreator("Test"), + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + { + name: "mailtemplate config nil", + args: args{ + ctx: authz.NewMockContext("orgID", "userID"), + existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, + new: nil, + aggCreator: models.NewAggregateCreator("Test"), + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + agg, err := MailTemplateAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) + + if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { + t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) + } + for i := 0; i < tt.res.eventLen; i++ { + if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { + t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) + } + if !tt.res.wantErr && agg.Events[i].Data == nil { + t.Errorf("should have data in event") + } + } + + if tt.res.wantErr && !tt.res.errFunc(err) { + t.Errorf("got wrong err: %v ", err) + } + }) + } +} + +func TestMailTemplateChangedAggregate(t *testing.T) { + type args struct { + ctx context.Context + existing *model.Org + new *iam_es_model.MailTemplate + aggCreator *models.AggregateCreator + } + type res struct { + eventLen int + eventTypes []models.EventType + wantErr bool + errFunc func(err error) bool + } + tests := []struct { + name string + args args + res res + }{ + { + name: "change mailtemplate", + args: args{ + ctx: authz.NewMockContext("orgID", "userID"), + existing: &model.Org{ + ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, + MailTemplate: &iam_es_model.MailTemplate{ + ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, + }, + }, + new: &iam_es_model.MailTemplate{ + ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, + Template: []byte(""), + }, + aggCreator: models.NewAggregateCreator("Test"), + }, + res: res{ + eventLen: 1, + eventTypes: []models.EventType{model.MailTemplateChanged}, + }, + }, + { + name: "existing org nil", + args: args{ + ctx: authz.NewMockContext("orgID", "userID"), + existing: nil, + aggCreator: models.NewAggregateCreator("Test"), + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + { + name: "mailtemplate config nil", + args: args{ + ctx: authz.NewMockContext("orgID", "userID"), + existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, + new: nil, + aggCreator: models.NewAggregateCreator("Test"), + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + agg, err := MailTemplateChangedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) + + if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { + t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) + } + for i := 0; i < tt.res.eventLen; i++ { + if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { + t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) + } + if !tt.res.wantErr && agg.Events[i].Data == nil { + t.Errorf("should have data in event") + } + } + + if tt.res.wantErr && !tt.res.errFunc(err) { + t.Errorf("got wrong err: %v ", err) + } + }) + } +} diff --git a/internal/org/repository/eventsourcing/mail_text.go b/internal/org/repository/eventsourcing/mail_text.go new file mode 100644 index 0000000000..2f6ea08b13 --- /dev/null +++ b/internal/org/repository/eventsourcing/mail_text.go @@ -0,0 +1,94 @@ +package eventsourcing + +import ( + "context" + + "github.com/caos/zitadel/internal/errors" + es_models "github.com/caos/zitadel/internal/eventstore/models" + iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" + "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" +) + +func MailTextAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, mailText *iam_es_model.MailText) func(ctx context.Context) (*es_models.Aggregate, error) { + return func(ctx context.Context) (*es_models.Aggregate, error) { + if mailText == nil { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Gk3Cn", "Errors.Internal") + } + agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) + if err != nil { + return nil, err + } + validationQuery := es_models.NewSearchQuery(). + AggregateTypeFilter(model.OrgAggregate). + AggregateIDFilter(existing.AggregateID) + + validation := checkExistingMailTextValidation(mailText, existing.MailTexts) + agg.SetPrecondition(validationQuery, validation) + return agg.AppendEvent(model.MailTextAdded, mailText) + } +} + +func MailTextChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, mailText *iam_es_model.MailText) func(ctx context.Context) (*es_models.Aggregate, error) { + return func(ctx context.Context) (*es_models.Aggregate, error) { + if mailText == nil { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Hog8a", "Errors.Internal") + } + agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) + if err != nil { + return nil, err + } + changes := make(map[string]interface{}, 2) + for _, exMailText := range existing.MailTexts { + if exMailText.MailTextType == mailText.MailTextType && exMailText.Language == mailText.Language { + changes = exMailText.Changes(mailText) + if len(changes) == 0 { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-DuRxA", "Errors.NoChangesFound") + } + } + } + return agg.AppendEvent(model.MailTextChanged, changes) + } +} + +func MailTextRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, mailText *iam_es_model.MailText) func(ctx context.Context) (*es_models.Aggregate, error) { + return func(ctx context.Context) (*es_models.Aggregate, error) { + if existing == nil { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-cJ5Wp", "Errors.Internal") + } + agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) + if err != nil { + return nil, err + } + changes := make(map[string]interface{}, 2) + for _, exMailText := range existing.MailTexts { + if exMailText.MailTextType == mailText.MailTextType && exMailText.Language == mailText.Language { + mailText.ButtonText = exMailText.ButtonText + mailText.Greeting = exMailText.Greeting + mailText.Text = exMailText.Text + mailText.Title = exMailText.Title + mailText.Subject = exMailText.Subject + mailText.PreHeader = exMailText.PreHeader + changes = exMailText.Changes(mailText) + if len(changes) == 0 { + return nil, errors.ThrowPreconditionFailed(nil, "EVENT-DuRxA", "Errors.NoChangesFound") + } + } + } + return agg.AppendEvent(model.MailTextRemoved, changes) + } +} + +func checkExistingMailTextValidation(mailText *iam_es_model.MailText, existingMailTexts []*iam_es_model.MailText) func(...*es_models.Event) error { + return func(events ...*es_models.Event) error { + existing := false + for _, text := range existingMailTexts { + if text.MailTextType == mailText.MailTextType && text.Language == mailText.Language { + existing = true + } + } + if existing { + return errors.ThrowPreconditionFailed(nil, "EVENT-zEZh7", "Errors.Org.MailText.AlreadyExists") + } + return nil + } +} diff --git a/internal/org/repository/eventsourcing/mail_text_test.go b/internal/org/repository/eventsourcing/mail_text_test.go new file mode 100644 index 0000000000..f6b1879ead --- /dev/null +++ b/internal/org/repository/eventsourcing/mail_text_test.go @@ -0,0 +1,188 @@ +package eventsourcing + +import ( + "context" + "testing" + + "github.com/caos/zitadel/internal/api/authz" + caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/models" + iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" + "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" +) + +func TestMailTextAddedAggregate(t *testing.T) { + type args struct { + ctx context.Context + existing *model.Org + new *iam_es_model.MailText + aggCreator *models.AggregateCreator + } + type res struct { + eventLen int + eventTypes []models.EventType + wantErr bool + errFunc func(err error) bool + } + tests := []struct { + name string + args args + res res + }{ + { + name: "add mailtext", + args: args{ + ctx: authz.NewMockContext("orgID", "userID"), + existing: &model.Org{ + ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, + }, + new: &iam_es_model.MailText{ + ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, + MailTextType: "Type", + Language: "DE", + }, + aggCreator: models.NewAggregateCreator("Test"), + }, + res: res{ + eventLen: 1, + eventTypes: []models.EventType{model.MailTextAdded}, + }, + }, + { + name: "existing org nil", + args: args{ + ctx: authz.NewMockContext("orgID", "userID"), + existing: nil, + aggCreator: models.NewAggregateCreator("Test"), + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + { + name: "mailtext config nil", + args: args{ + ctx: authz.NewMockContext("orgID", "userID"), + existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, + new: nil, + aggCreator: models.NewAggregateCreator("Test"), + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + agg, err := MailTextAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) + + if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { + t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) + } + for i := 0; i < tt.res.eventLen; i++ { + if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { + t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) + } + if !tt.res.wantErr && agg.Events[i].Data == nil { + t.Errorf("should have data in event") + } + } + + if tt.res.wantErr && !tt.res.errFunc(err) { + t.Errorf("got wrong err: %v ", err) + } + }) + } +} + +func TestMailTextChangedAggregate(t *testing.T) { + type args struct { + ctx context.Context + existing *model.Org + new *iam_es_model.MailText + aggCreator *models.AggregateCreator + } + type res struct { + eventLen int + eventTypes []models.EventType + wantErr bool + errFunc func(err error) bool + } + tests := []struct { + name string + args args + res res + }{ + { + name: "change mailtext", + args: args{ + ctx: authz.NewMockContext("orgID", "userID"), + existing: &model.Org{ + ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, + MailTexts: []*iam_es_model.MailText{&iam_es_model.MailText{ + ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, + }, + }, + new: &iam_es_model.MailText{ + ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, + MailTextType: "Type", + Language: "DE", + Subject: "Subject", + }, + aggCreator: models.NewAggregateCreator("Test"), + }, + res: res{ + eventLen: 1, + eventTypes: []models.EventType{model.MailTextChanged}, + }, + }, + { + name: "existing org nil", + args: args{ + ctx: authz.NewMockContext("orgID", "userID"), + existing: nil, + aggCreator: models.NewAggregateCreator("Test"), + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + { + name: "mailtext config nil", + args: args{ + ctx: authz.NewMockContext("orgID", "userID"), + existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, + new: nil, + aggCreator: models.NewAggregateCreator("Test"), + }, + res: res{ + wantErr: true, + errFunc: caos_errs.IsPreconditionFailed, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + agg, err := MailTextChangedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) + + if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { + t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) + } + for i := 0; i < tt.res.eventLen; i++ { + if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { + t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) + } + if !tt.res.wantErr && agg.Events[i].Data == nil { + t.Errorf("should have data in event") + } + } + + if tt.res.wantErr && !tt.res.errFunc(err) { + t.Errorf("got wrong err: %v ", err) + } + }) + } +} diff --git a/internal/org/repository/eventsourcing/model/mail_template.go b/internal/org/repository/eventsourcing/model/mail_template.go new file mode 100644 index 0000000000..4a0f4aff5d --- /dev/null +++ b/internal/org/repository/eventsourcing/model/mail_template.go @@ -0,0 +1,31 @@ +package model + +import ( + es_models "github.com/caos/zitadel/internal/eventstore/models" + iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" +) + +func (o *Org) appendAddMailTemplateEvent(event *es_models.Event) error { + o.MailTemplate = new(iam_es_model.MailTemplate) + err := o.MailTemplate.SetDataLabel(event) + if err != nil { + return err + } + o.MailTemplate.ObjectRoot.CreationDate = event.CreationDate + return nil +} + +func (o *Org) appendChangeMailTemplateEvent(event *es_models.Event) error { + mailTemplate := &iam_es_model.MailTemplate{} + err := mailTemplate.SetDataLabel(event) + if err != nil { + return err + } + mailTemplate.ObjectRoot.ChangeDate = event.CreationDate + o.MailTemplate = mailTemplate + return nil +} + +func (o *Org) appendRemoveMailTemplateEvent(event *es_models.Event) { + o.MailTemplate = nil +} diff --git a/internal/org/repository/eventsourcing/model/mail_template_test.go b/internal/org/repository/eventsourcing/model/mail_template_test.go new file mode 100644 index 0000000000..2ec769de01 --- /dev/null +++ b/internal/org/repository/eventsourcing/model/mail_template_test.go @@ -0,0 +1,83 @@ +package model + +import ( + "encoding/json" + "testing" + + es_models "github.com/caos/zitadel/internal/eventstore/models" + iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" +) + +func TestAppendAddMailTemplateEvent(t *testing.T) { + type args struct { + org *Org + policy *iam_es_model.MailTemplate + event *es_models.Event + } + tests := []struct { + name string + args args + result *Org + }{ + { + name: "append add label policy event", + args: args{ + org: &Org{}, + policy: &iam_es_model.MailTemplate{Template: []byte("")}, + event: &es_models.Event{}, + }, + result: &Org{MailTemplate: &iam_es_model.MailTemplate{Template: []byte("")}}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.args.policy != nil { + data, _ := json.Marshal(tt.args.policy) + tt.args.event.Data = data + } + tt.args.org.appendAddMailTemplateEvent(tt.args.event) + if string(tt.result.MailTemplate.Template) != string(tt.args.org.MailTemplate.Template) { + t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.MailTemplate.Template, tt.args.org.MailTemplate.Template) + } + }) + } +} + +func TestAppendChangeMailTemplateEvent(t *testing.T) { + type args struct { + org *Org + policy *iam_es_model.MailTemplate + event *es_models.Event + } + tests := []struct { + name string + args args + result *Org + }{ + { + name: "append change label policy event", + args: args{ + org: &Org{MailTemplate: &iam_es_model.MailTemplate{ + Template: []byte(""), + }}, + policy: &iam_es_model.MailTemplate{Template: []byte("")}, + event: &es_models.Event{}, + }, + result: &Org{MailTemplate: &iam_es_model.MailTemplate{ + Template: []byte(""), + }}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.args.policy != nil { + data, _ := json.Marshal(tt.args.policy) + tt.args.event.Data = data + } + tt.args.org.appendChangeMailTemplateEvent(tt.args.event) + if string(tt.result.MailTemplate.Template) != string(tt.args.org.MailTemplate.Template) { + t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.MailTemplate.Template, tt.args.org.MailTemplate.Template) + } + }) + } +} diff --git a/internal/org/repository/eventsourcing/model/mail_text.go b/internal/org/repository/eventsourcing/model/mail_text.go new file mode 100644 index 0000000000..964cb2dea9 --- /dev/null +++ b/internal/org/repository/eventsourcing/model/mail_text.go @@ -0,0 +1,44 @@ +package model + +import ( + es_models "github.com/caos/zitadel/internal/eventstore/models" + iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" +) + +func (o *Org) appendAddMailTextEvent(event *es_models.Event) error { + mailText := &iam_es_model.MailText{} + err := mailText.SetDataLabel(event) + if err != nil { + return err + } + mailText.ObjectRoot.CreationDate = event.CreationDate + o.MailTexts = append(o.MailTexts, mailText) + return nil +} + +func (o *Org) appendChangeMailTextEvent(event *es_models.Event) error { + mailText := &iam_es_model.MailText{} + err := mailText.SetDataLabel(event) + if err != nil { + return err + } + mailText.ObjectRoot.ChangeDate = event.CreationDate + if n, m := iam_es_model.GetMailText(o.MailTexts, mailText.MailTextType, mailText.Language); m != nil { + o.MailTexts[n] = mailText + } + return nil +} + +func (o *Org) appendRemoveMailTextEvent(event *es_models.Event) error { + mailText := &iam_es_model.MailText{} + err := mailText.SetDataLabel(event) + if err != nil { + return err + } + if n, m := iam_es_model.GetMailText(o.MailTexts, mailText.MailTextType, mailText.Language); m != nil { + o.MailTexts[n] = o.MailTexts[len(o.MailTexts)-1] + o.MailTexts[len(o.MailTexts)-1] = nil + o.MailTexts = o.MailTexts[:len(o.MailTexts)-1] + } + return nil +} diff --git a/internal/org/repository/eventsourcing/model/mail_text_test.go b/internal/org/repository/eventsourcing/model/mail_text_test.go new file mode 100644 index 0000000000..640914ad82 --- /dev/null +++ b/internal/org/repository/eventsourcing/model/mail_text_test.go @@ -0,0 +1,91 @@ +package model + +import ( + "encoding/json" + "testing" + + es_models "github.com/caos/zitadel/internal/eventstore/models" + iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" +) + +func TestAppendAddMailTextEvent(t *testing.T) { + type args struct { + org *Org + mailText *iam_es_model.MailText + event *es_models.Event + } + tests := []struct { + name string + args args + result *Org + }{ + { + name: "append add mail text event", + args: args{ + org: &Org{}, + mailText: &iam_es_model.MailText{MailTextType: "Type", Language: "DE"}, + event: &es_models.Event{}, + }, + result: &Org{MailTexts: []*iam_es_model.MailText{&iam_es_model.MailText{MailTextType: "Type", Language: "DE"}}}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.args.mailText != nil { + data, _ := json.Marshal(tt.args.mailText) + tt.args.event.Data = data + } + tt.args.org.appendAddMailTextEvent(tt.args.event) + if len(tt.args.org.MailTexts) != 1 { + t.Errorf("got wrong result should have one mailtext actual: %v ", len(tt.args.org.MailTexts)) + } + if tt.result.MailTexts[0].Language != tt.args.org.MailTexts[0].Language { + t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.MailTexts[0].Language, tt.args.org.MailTexts[0].Language) + } + }) + } +} + +func TestAppendChangeMailTextEvent(t *testing.T) { + type args struct { + org *Org + mailText *iam_es_model.MailText + event *es_models.Event + } + tests := []struct { + name string + args args + result *Org + }{ + { + name: "append change mail text event", + args: args{ + org: &Org{MailTexts: []*iam_es_model.MailText{&iam_es_model.MailText{ + Language: "DE", + MailTextType: "TypeX", + }}}, + mailText: &iam_es_model.MailText{MailTextType: "Type", Language: "DE"}, + event: &es_models.Event{}, + }, + result: &Org{MailTexts: []*iam_es_model.MailText{&iam_es_model.MailText{ + Language: "DE", + MailTextType: "Type", + }}}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.args.mailText != nil { + data, _ := json.Marshal(tt.args.mailText) + tt.args.event.Data = data + } + tt.args.org.appendChangeMailTextEvent(tt.args.event) + if len(tt.args.org.MailTexts) != 1 { + t.Errorf("got wrong result should have one mailtext actual: %v ", len(tt.args.org.MailTexts)) + } + if tt.result.MailTexts[0].Language != tt.args.org.MailTexts[0].Language { + t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.MailTexts[0].Language, tt.args.org.MailTexts[0].Language) + } + }) + } +} diff --git a/internal/org/repository/eventsourcing/model/org.go b/internal/org/repository/eventsourcing/model/org.go index c4be52ccb1..1998292639 100644 --- a/internal/org/repository/eventsourcing/model/org.go +++ b/internal/org/repository/eventsourcing/model/org.go @@ -25,6 +25,8 @@ type Org struct { Members []*OrgMember `json:"-"` OrgIAMPolicy *iam_es_model.OrgIAMPolicy `json:"-"` LabelPolicy *iam_es_model.LabelPolicy `json:"-"` + MailTemplate *iam_es_model.MailTemplate `json:"-"` + MailTexts []*iam_es_model.MailText `json:"-"` IDPs []*iam_es_model.IDPConfig `json:"-"` LoginPolicy *iam_es_model.LoginPolicy `json:"-"` PasswordComplexityPolicy *iam_es_model.PasswordComplexityPolicy `json:"-"` @@ -36,11 +38,13 @@ func OrgFromModel(org *org_model.Org) *Org { members := OrgMembersFromModel(org.Members) domains := OrgDomainsFromModel(org.Domains) idps := iam_es_model.IDPConfigsFromModel(org.IDPs) + mailTexts := iam_es_model.MailTextsFromModel(org.MailTexts) converted := &Org{ ObjectRoot: org.ObjectRoot, Name: org.Name, State: int32(org.State), Domains: domains, + MailTexts: mailTexts, Members: members, IDPs: idps, } @@ -53,6 +57,9 @@ func OrgFromModel(org *org_model.Org) *Org { if org.LabelPolicy != nil { converted.LabelPolicy = iam_es_model.LabelPolicyFromModel(org.LabelPolicy) } + if org.MailTemplate != nil { + converted.MailTemplate = iam_es_model.MailTemplateFromModel(org.MailTemplate) + } if org.PasswordComplexityPolicy != nil { converted.PasswordComplexityPolicy = iam_es_model.PasswordComplexityPolicyFromModel(org.PasswordComplexityPolicy) } @@ -72,6 +79,7 @@ func OrgToModel(org *Org) *org_model.Org { State: org_model.OrgState(org.State), Domains: OrgDomainsToModel(org.Domains), Members: OrgMembersToModel(org.Members), + MailTexts: iam_es_model.MailTextsToModel(org.MailTexts), IDPs: iam_es_model.IDPConfigsToModel(org.IDPs), } if org.OrgIAMPolicy != nil { @@ -83,6 +91,9 @@ func OrgToModel(org *Org) *org_model.Org { if org.LabelPolicy != nil { converted.LabelPolicy = iam_es_model.LabelPolicyToModel(org.LabelPolicy) } + if org.MailTemplate != nil { + converted.MailTemplate = iam_es_model.MailTemplateToModel(org.MailTemplate) + } if org.PasswordComplexityPolicy != nil { converted.PasswordComplexityPolicy = iam_es_model.PasswordComplexityPolicyToModel(org.PasswordComplexityPolicy) } @@ -199,6 +210,18 @@ func (o *Org) AppendEvent(event *es_models.Event) (err error) { err = o.appendAddIdpProviderToLoginPolicyEvent(event) case LoginPolicyIDPProviderRemoved: err = o.appendRemoveIdpProviderFromLoginPolicyEvent(event) + case MailTemplateAdded: + err = o.appendAddMailTemplateEvent(event) + case MailTemplateChanged: + err = o.appendChangeMailTemplateEvent(event) + case MailTemplateRemoved: + o.appendRemoveMailTemplateEvent(event) + case MailTextAdded: + err = o.appendAddMailTextEvent(event) + case MailTextChanged: + err = o.appendChangeMailTextEvent(event) + case MailTextRemoved: + o.appendRemoveMailTextEvent(event) case LoginPolicySecondFactorAdded: err = o.appendAddSecondFactorToLoginPolicyEvent(event) case LoginPolicySecondFactorRemoved: diff --git a/internal/org/repository/eventsourcing/model/types.go b/internal/org/repository/eventsourcing/model/types.go index 1c40083149..0f21da6749 100644 --- a/internal/org/repository/eventsourcing/model/types.go +++ b/internal/org/repository/eventsourcing/model/types.go @@ -60,6 +60,13 @@ const ( LabelPolicyChanged models.EventType = "org.policy.label.changed" LabelPolicyRemoved models.EventType = "org.policy.label.removed" + MailTemplateAdded models.EventType = "org.mail.template.added" + MailTemplateChanged models.EventType = "org.mail.template.changed" + MailTemplateRemoved models.EventType = "org.mail.template.removed" + MailTextAdded models.EventType = "org.mail.text.added" + MailTextChanged models.EventType = "org.mail.text.changed" + MailTextRemoved models.EventType = "org.mail.text.removed" + PasswordComplexityPolicyAdded models.EventType = "org.policy.password.complexity.added" PasswordComplexityPolicyChanged models.EventType = "org.policy.password.complexity.changed" PasswordComplexityPolicyRemoved models.EventType = "org.policy.password.complexity.removed" diff --git a/internal/project/model/project_role_view.go b/internal/project/model/project_role_view.go index d49540cb8e..0f358b36ce 100644 --- a/internal/project/model/project_role_view.go +++ b/internal/project/model/project_role_view.go @@ -1,8 +1,9 @@ package model import ( - "github.com/caos/zitadel/internal/model" "time" + + "github.com/caos/zitadel/internal/model" ) type ProjectRoleView struct { @@ -13,6 +14,7 @@ type ProjectRoleView struct { DisplayName string Group string CreationDate time.Time + ChangeDate time.Time Sequence uint64 } diff --git a/internal/project/repository/view/model/project_role.go b/internal/project/repository/view/model/project_role.go index 986b1375b1..b7adcb3d0f 100644 --- a/internal/project/repository/view/model/project_role.go +++ b/internal/project/repository/view/model/project_role.go @@ -2,12 +2,13 @@ package model import ( "encoding/json" + "time" + "github.com/caos/logging" caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/project/model" es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model" - "time" ) const ( @@ -27,6 +28,7 @@ type ProjectRoleView struct { ResourceOwner string `json:"-" gorm:"resource_owner"` CreationDate time.Time `json:"-" gorm:"column:creation_date"` + ChangeDate time.Time `json:"-" gorm:"column:change_date"` } func ProjectRoleViewFromModel(role *model.ProjectRoleView) *ProjectRoleView { @@ -39,6 +41,7 @@ func ProjectRoleViewFromModel(role *model.ProjectRoleView) *ProjectRoleView { Group: role.Group, Sequence: role.Sequence, CreationDate: role.CreationDate, + ChangeDate: role.ChangeDate, } } @@ -52,6 +55,7 @@ func ProjectRoleToModel(role *ProjectRoleView) *model.ProjectRoleView { Group: role.Group, Sequence: role.Sequence, CreationDate: role.CreationDate, + ChangeDate: role.ChangeDate, } } @@ -71,6 +75,7 @@ func (r *ProjectRoleView) AppendEvent(event *models.Event) (err error) { r.CreationDate = event.CreationDate err = r.SetData(event) case es_model.ProjectRoleChanged: + r.ChangeDate = event.CreationDate err = r.SetData(event) } return err diff --git a/internal/setup/config.go b/internal/setup/config.go index c0f19fb6d9..e5ce1e4487 100644 --- a/internal/setup/config.go +++ b/internal/setup/config.go @@ -15,6 +15,7 @@ type IAMSetUp struct { Step7 *command.Step7 Step8 *command.Step8 Step9 *command.Step9 + Step10 *command.Step10 } func (setup *IAMSetUp) Steps(currentDone domain.Step) ([]command.Step, error) { @@ -30,6 +31,7 @@ func (setup *IAMSetUp) Steps(currentDone domain.Step) ([]command.Step, error) { setup.Step7, setup.Step8, setup.Step9, + setup.Step10, } { if step.Step() <= currentDone { continue diff --git a/internal/setup/step10.go b/internal/setup/step10.go new file mode 100644 index 0000000000..4316f87776 --- /dev/null +++ b/internal/setup/step10.go @@ -0,0 +1,98 @@ +package setup + +// +//type Step10 struct { +// DefaultMailTemplate iam_model.MailTemplate +// DefaultMailTexts []iam_model.MailText +// +// setup *Setup +//} +// +//func (s *Step10) isNil() bool { +// return s == nil +//} +// +//func (step *Step10) step() iam_model.Step { +// return iam_model.Step10 +//} +// +//func (step *Step10) init(setup *Setup) { +// step.setup = setup +//} +// +//func (step *Step10) execute(ctx context.Context) (*iam_model.IAM, error) { +// iam, agg, err := step.mailTemplate(ctx, &step.DefaultMailTemplate) +// if err != nil { +// logging.Log("SETUP-1UYCt").WithField("step", step.step()).WithError(err).Error("unable to finish setup (Mail template)") +// return nil, err +// } +// iam, agg, push, err := step.setup.IamEvents.PrepareSetupDone(ctx, iam, agg, step.step()) +// if err != nil { +// logging.Log("SETUP-fMLsb").WithField("step", step.step()).WithError(err).Error("unable to finish setup (prepare setup done)") +// return nil, err +// } +// err = es_sdk.PushAggregates(ctx, push, iam.AppendEvents, agg) +// if err != nil { +// logging.Log("SETUP-GuS3f").WithField("step", step.step()).WithError(err).Error("unable to finish setup") +// return nil, err +// } +// +// iam, agg, err = step.defaultMailTexts(ctx, &step.DefaultMailTexts) +// if err != nil { +// logging.Log("SETUP-p4oWq").WithError(err).Error("unable to set up defaultMailTexts") +// return nil, err +// } +// iam, agg, push, err = step.setup.IamEvents.PrepareSetupDone(ctx, iam, agg, step.step()) +// if err != nil { +// logging.Log("SETUP-fMLsb").WithField("step", step.step()).WithError(err).Error("unable to finish setup (prepare setup done)") +// return nil, err +// } +// err = es_sdk.PushAggregates(ctx, push, iam.AppendEvents, agg) +// if err != nil { +// logging.Log("SETUP-GuS3f").WithField("step", step.step()).WithError(err).Error("unable to finish setup") +// return nil, err +// } +// +// return iam_es_model.IAMToModel(iam), nil +//} +// +//func (step *Step10) mailTemplate(ctx context.Context, mailTemplate *iam_model.MailTemplate) (*iam_es_model.IAM, *models.Aggregate, error) { +// logging.Log("SETUP-cNrF3").Info("setting up mail template") +// mailTemplate.AggregateID = step.setup.iamID +// iam, aggregate, err := step.setup.IamEvents.PrepareAddMailTemplate(ctx, mailTemplate) +// if err != nil { +// return nil, nil, err +// } +// return iam, aggregate, nil +//} +// +//func (step *Step10) defaultMailTexts(ctx context.Context, defaultMailTexts *[]iam_model.MailText) (*iam_es_model.IAM, *models.Aggregate, error) { +// logging.Log("SETUP-dsTh3").Info("setting up defaultMailTexts") +// iam := &iam_es_model.IAM{} +// var aggregate *models.Aggregate +// for index, iamDefaultMailText := range *defaultMailTexts { +// iaml, aggregatel, err := step.defaultMailText(ctx, &iamDefaultMailText) +// if err != nil { +// logging.LogWithFields("SETUP-IlLif", "DefaultMailText", iamDefaultMailText.MailTextType).WithError(err).Error("unable to create defaultMailText") +// return nil, nil, err +// } +// if index == 0 { +// aggregate = aggregatel +// } else { +// aggregate.Events = append(aggregate.Events, aggregatel.Events...) +// } +// iam = iaml +// } +// logging.Log("SETUP-dgjT4").Info("defaultMailTexts set up") +// return iam, aggregate, nil +//} +// +//func (step *Step10) defaultMailText(ctx context.Context, mailText *iam_model.MailText) (*iam_es_model.IAM, *models.Aggregate, error) { +// logging.Log("SETUP-cNrF3").Info("setting up mail text") +// mailText.AggregateID = step.setup.iamID +// iam, aggregate, err := step.setup.IamEvents.PrepareAddMailText(ctx, mailText) +// if err != nil { +// return nil, nil, err +// } +// return iam, aggregate, nil +//} diff --git a/internal/ui/login/handler/password_complexity_policy_handler.go b/internal/ui/login/handler/password_complexity_policy_handler.go index e1d35d66a8..34781be6d7 100644 --- a/internal/ui/login/handler/password_complexity_policy_handler.go +++ b/internal/ui/login/handler/password_complexity_policy_handler.go @@ -1,12 +1,13 @@ package handler import ( - "github.com/caos/zitadel/internal/auth_request/model" - "github.com/caos/zitadel/internal/errors" - iam_model "github.com/caos/zitadel/internal/iam/model" "net/http" "regexp" "strconv" + + "github.com/caos/zitadel/internal/auth_request/model" + "github.com/caos/zitadel/internal/errors" + iam_model "github.com/caos/zitadel/internal/iam/model" ) const ( @@ -46,24 +47,24 @@ func (l *Login) getPasswordComplexityPolicyByUserID(r *http.Request, userID stri } func (l *Login) generatePolicyDescription(r *http.Request, policy *iam_model.PasswordComplexityPolicyView) (string, error) { - description := "