mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-10 04:43:40 +00:00
Merge branch 'v2-alpha' into cy10
This commit is contained in:
commit
53a3ba8acf
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -2,7 +2,7 @@
|
|||||||
name: "\U0001F41B Bug report"
|
name: "\U0001F41B Bug report"
|
||||||
about: Create a report to help us improve
|
about: Create a report to help us improve
|
||||||
title: ''
|
title: ''
|
||||||
labels: bug
|
labels: 'state: triage, type: bug'
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
13
.github/ISSUE_TEMPLATE/okr.md
vendored
13
.github/ISSUE_TEMPLATE/okr.md
vendored
@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
name: OKR
|
|
||||||
about: The objective key result is an overarching goal that we are working towards.
|
|
||||||
title: ''
|
|
||||||
labels: OKR
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
OKR description
|
|
||||||
|
|
||||||
- [ ] Link to subordinate story
|
|
||||||
- [ ] Link to subordinate story
|
|
14
.github/ISSUE_TEMPLATE/story.md
vendored
14
.github/ISSUE_TEMPLATE/story.md
vendored
@ -1,14 +0,0 @@
|
|||||||
---
|
|
||||||
name: Story
|
|
||||||
about: A story describes the basic objective and contains several tasks that are to
|
|
||||||
be implemented
|
|
||||||
title: ''
|
|
||||||
labels: story
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
As a [type of user], I want [a goal or objective], so that [customer benefit or value].
|
|
||||||
|
|
||||||
- [ ] Link to subordinate task
|
|
||||||
- [ ] Link to subordinate task
|
|
5
.github/ISSUE_TEMPLATE/task.md
vendored
5
.github/ISSUE_TEMPLATE/task.md
vendored
@ -3,16 +3,13 @@ name: Task
|
|||||||
about: A task describes what is to be implemented and which acceptance criteria must
|
about: A task describes what is to be implemented and which acceptance criteria must
|
||||||
be met.
|
be met.
|
||||||
title: ''
|
title: ''
|
||||||
labels: task
|
labels: 'state: triage'
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Description
|
Description
|
||||||
|
|
||||||
- [ ] Todo
|
|
||||||
- [ ] Todo
|
|
||||||
|
|
||||||
**Acceptance criteria**
|
**Acceptance criteria**
|
||||||
- [ ] ...
|
- [ ] ...
|
||||||
- [ ] ...
|
- [ ] ...
|
||||||
|
@ -9,6 +9,8 @@ release:
|
|||||||
|
|
||||||
before:
|
before:
|
||||||
hooks:
|
hooks:
|
||||||
|
# this file would invalidate go source caches
|
||||||
|
- sh -c "rm openapi/statik/statik.go || true"
|
||||||
- docker build -f build/grpc/Dockerfile -t zitadel-base:local .
|
- docker build -f build/grpc/Dockerfile -t zitadel-base:local .
|
||||||
- docker build -f build/zitadel/Dockerfile . -t zitadel-test-base --target go-test
|
- docker build -f build/zitadel/Dockerfile . -t zitadel-test-base --target go-test
|
||||||
- docker build -f build/zitadel/Dockerfile . -t zitadel-go-test --target go-codecov -o .artifacts/codecov
|
- docker build -f build/zitadel/Dockerfile . -t zitadel-go-test --target go-codecov -o .artifacts/codecov
|
||||||
|
@ -3,7 +3,7 @@ module.exports = {
|
|||||||
{name: 'main'},
|
{name: 'main'},
|
||||||
{name: '1.x.x', range: '1.x.x', channel: '1.x.x'},
|
{name: '1.x.x', range: '1.x.x', channel: '1.x.x'},
|
||||||
{name: 'v2-alpha', prerelease: true},
|
{name: 'v2-alpha', prerelease: true},
|
||||||
{name: 'auth-users', prerelease: true},
|
{name: 'scheduler', prerelease: true},
|
||||||
],
|
],
|
||||||
plugins: [
|
plugins: [
|
||||||
"@semantic-release/commit-analyzer"
|
"@semantic-release/commit-analyzer"
|
||||||
|
10
README.md
10
README.md
@ -142,16 +142,6 @@ Delegate the right to assign roles to another organization
|
|||||||
Customize login and console with your design
|
Customize login and console with your design
|
||||||
![private_labeling](https://user-images.githubusercontent.com/1366906/123089110-d148ff80-d426-11eb-9598-32b506f6d4fd.gif)
|
![private_labeling](https://user-images.githubusercontent.com/1366906/123089110-d148ff80-d426-11eb-9598-32b506f6d4fd.gif)
|
||||||
|
|
||||||
## Usage Data
|
|
||||||
|
|
||||||
ZITADEL components send errors and usage data to CAOS Ltd., so that we are able to identify code improvement potential. If you don't want to send this data or don't have an internet connection, pass the global flag `--disable-analytics` when using zitadelctl. For disabling ingestion for already-running components, execute the takeoff command again with the `` flag.
|
|
||||||
|
|
||||||
We try to distinguishing the environments from which events come from. As environment identifier, we enrich the events by the domain you have configured in zitadel.yml, as soon as it's available. When it's not available and you passed the --gitops flag, we defer the environment identifier from your git repository URL.
|
|
||||||
|
|
||||||
Besides from errors that don't clearly come from misconfiguration or cli misusage, we send an initial event when any binary is started. This is a "<component> invoked" event along with the flags that are passed to it, except secret values of course.
|
|
||||||
|
|
||||||
We only ingest operational data. Your ZITADEL workload data from the IAM application itself is never sent anywhere unless you chose to integrate other systems yourself.
|
|
||||||
|
|
||||||
## Security
|
## Security
|
||||||
|
|
||||||
See the policy [here](./SECURITY.md)
|
See the policy [here](./SECURITY.md)
|
||||||
|
@ -3,10 +3,16 @@ ARG NODE_VERSION=16
|
|||||||
#######################
|
#######################
|
||||||
## With this step we prepare all node_modules, this helps caching the build
|
## With this step we prepare all node_modules, this helps caching the build
|
||||||
## Speed up this step by mounting your local node_modules directory
|
## Speed up this step by mounting your local node_modules directory
|
||||||
|
## We also copy and generate the source code
|
||||||
#######################
|
#######################
|
||||||
FROM node:${NODE_VERSION} as npm-base
|
FROM node:${NODE_VERSION} as npm-base
|
||||||
WORKDIR /console
|
WORKDIR /console
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
COPY console/package.json console/package-lock.json ./
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
# Sources
|
||||||
COPY console .
|
COPY console .
|
||||||
COPY --from=zitadel-base:local /proto /proto
|
COPY --from=zitadel-base:local /proto /proto
|
||||||
COPY --from=zitadel-base:local /usr/local/bin /usr/local/bin/.
|
COPY --from=zitadel-base:local /usr/local/bin /usr/local/bin/.
|
||||||
@ -24,12 +30,8 @@ COPY --from=npm-base /console/src/app/proto/generated /console/src/app/proto/gen
|
|||||||
#######################
|
#######################
|
||||||
FROM npm-base as angular-build
|
FROM npm-base as angular-build
|
||||||
|
|
||||||
COPY console/package.json console/package-lock.json ./
|
|
||||||
RUN npm ci
|
|
||||||
|
|
||||||
RUN npm run lint
|
RUN npm run lint
|
||||||
RUN npm run prodbuild
|
RUN npm run prodbuild
|
||||||
RUN ls -la /console/dist/console
|
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
## Only Copy Assets
|
## Only Copy Assets
|
||||||
|
@ -5,18 +5,17 @@ ARG GO_VERSION=1.17
|
|||||||
## Speed up this step by mounting your local go mod pkg directory
|
## Speed up this step by mounting your local go mod pkg directory
|
||||||
#######################
|
#######################
|
||||||
FROM golang:${GO_VERSION} as go-dep
|
FROM golang:${GO_VERSION} as go-dep
|
||||||
RUN mkdir -p src/github.com/zitadel/zitadel
|
|
||||||
WORKDIR /go/src/github.com/zitadel/zitadel
|
WORKDIR /go/src/github.com/zitadel/zitadel
|
||||||
|
|
||||||
#download modules
|
#download modules
|
||||||
COPY . .
|
COPY go.mod ./
|
||||||
|
COPY go.sum ./
|
||||||
RUN go mod download
|
RUN go mod download
|
||||||
|
|
||||||
# install tools
|
# install tools
|
||||||
COPY tools ./tools
|
COPY tools ./tools
|
||||||
RUN ./tools/install.sh
|
RUN ./tools/install.sh
|
||||||
|
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
## generates static files
|
## generates static files
|
||||||
#######################
|
#######################
|
||||||
@ -47,17 +46,20 @@ COPY internal/api/assets/generator internal/api/assets/generator
|
|||||||
COPY internal/config internal/config
|
COPY internal/config internal/config
|
||||||
COPY internal/errors internal/errors
|
COPY internal/errors internal/errors
|
||||||
|
|
||||||
RUN build/zitadel/generate-grpc.sh \
|
RUN build/zitadel/generate-grpc.sh && \
|
||||||
&& go generate openapi/statik/generate.go \
|
go generate openapi/statik/generate.go && \
|
||||||
&& mkdir -p docs/apis/assets/ \
|
mkdir -p docs/apis/assets/ && \
|
||||||
&& go run internal/api/assets/generator/asset_generator.go -directory=internal/api/assets/generator/ -assets=docs/apis/assets/assets.md
|
go run internal/api/assets/generator/asset_generator.go -directory=internal/api/assets/generator/ -assets=docs/apis/assets/assets.md
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
## Go base build
|
## Go base build
|
||||||
#######################
|
#######################
|
||||||
FROM go-stub as go-base
|
FROM go-stub as go-base
|
||||||
# copy remaining zitadel files
|
# copy remaining zitadel files
|
||||||
COPY . .
|
COPY cmd cmd
|
||||||
|
COPY internal internal
|
||||||
|
COPY pkg pkg
|
||||||
|
COPY openapi openapi
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
## copy for local dev
|
## copy for local dev
|
||||||
|
60
cmd/setup/config_change.go
Normal file
60
cmd/setup/config_change.go
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package setup
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/command"
|
||||||
|
"github.com/zitadel/zitadel/internal/config/systemdefaults"
|
||||||
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
|
)
|
||||||
|
|
||||||
|
type externalConfigChange struct {
|
||||||
|
es *eventstore.Eventstore
|
||||||
|
ExternalDomain string `json:"externalDomain"`
|
||||||
|
ExternalSecure bool `json:"externalSecure"`
|
||||||
|
ExternalPort uint16 `json:"externalPort"`
|
||||||
|
|
||||||
|
currentExternalDomain string
|
||||||
|
currentExternalSecure bool
|
||||||
|
currentExternalPort uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mig *externalConfigChange) SetLastExecution(lastRun map[string]interface{}) {
|
||||||
|
mig.currentExternalDomain, _ = lastRun["externalDomain"].(string)
|
||||||
|
externalPort, _ := lastRun["externalPort"].(float64)
|
||||||
|
mig.currentExternalPort = uint16(externalPort)
|
||||||
|
mig.currentExternalSecure, _ = lastRun["externalSecure"].(bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mig *externalConfigChange) Check() bool {
|
||||||
|
return mig.currentExternalSecure != mig.ExternalSecure ||
|
||||||
|
mig.currentExternalPort != mig.ExternalPort ||
|
||||||
|
mig.currentExternalDomain != mig.ExternalDomain
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mig *externalConfigChange) Execute(ctx context.Context) error {
|
||||||
|
cmd, err := command.StartCommands(mig.es,
|
||||||
|
systemdefaults.SystemDefaults{},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
mig.ExternalDomain,
|
||||||
|
mig.ExternalSecure,
|
||||||
|
mig.ExternalPort,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return cmd.ChangeSystemConfig(ctx, mig.currentExternalDomain, mig.currentExternalPort, mig.currentExternalSecure)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mig *externalConfigChange) String() string {
|
||||||
|
return "config_change"
|
||||||
|
}
|
@ -54,6 +54,8 @@ func Flags(cmd *cobra.Command) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Setup(config *Config, steps *Steps, masterKey string) {
|
func Setup(config *Config, steps *Steps, masterKey string) {
|
||||||
|
logging.Info("setup started")
|
||||||
|
|
||||||
dbClient, err := database.Connect(config.Database)
|
dbClient, err := database.Connect(config.Database)
|
||||||
logging.OnError(err).Fatal("unable to connect to database")
|
logging.OnError(err).Fatal("unable to connect to database")
|
||||||
|
|
||||||
@ -76,6 +78,15 @@ func Setup(config *Config, steps *Steps, masterKey string) {
|
|||||||
steps.S3DefaultInstance.externalSecure = config.ExternalSecure
|
steps.S3DefaultInstance.externalSecure = config.ExternalSecure
|
||||||
steps.S3DefaultInstance.externalPort = config.ExternalPort
|
steps.S3DefaultInstance.externalPort = config.ExternalPort
|
||||||
|
|
||||||
|
repeatableSteps := []migration.RepeatableMigration{
|
||||||
|
&externalConfigChange{
|
||||||
|
es: eventstoreClient,
|
||||||
|
ExternalDomain: config.ExternalDomain,
|
||||||
|
ExternalPort: config.ExternalPort,
|
||||||
|
ExternalSecure: config.ExternalSecure,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
err = migration.Migrate(ctx, eventstoreClient, steps.s1ProjectionTable)
|
err = migration.Migrate(ctx, eventstoreClient, steps.s1ProjectionTable)
|
||||||
logging.OnError(err).Fatal("unable to migrate step 1")
|
logging.OnError(err).Fatal("unable to migrate step 1")
|
||||||
@ -83,14 +94,9 @@ func Setup(config *Config, steps *Steps, masterKey string) {
|
|||||||
logging.OnError(err).Fatal("unable to migrate step 2")
|
logging.OnError(err).Fatal("unable to migrate step 2")
|
||||||
err = migration.Migrate(ctx, eventstoreClient, steps.S3DefaultInstance)
|
err = migration.Migrate(ctx, eventstoreClient, steps.S3DefaultInstance)
|
||||||
logging.OnError(err).Fatal("unable to migrate step 3")
|
logging.OnError(err).Fatal("unable to migrate step 3")
|
||||||
}
|
|
||||||
|
|
||||||
func initSteps(v *viper.Viper, files ...string) func() {
|
for _, repeatableStep := range repeatableSteps {
|
||||||
return func() {
|
err = migration.Migrate(ctx, eventstoreClient, repeatableStep)
|
||||||
for _, file := range files {
|
logging.OnError(err).Fatalf("unable to migrate repeatable step: %s", repeatableStep.String())
|
||||||
v.SetConfigFile(file)
|
|
||||||
err := v.MergeInConfig()
|
|
||||||
logging.WithFields("file", file).OnError(err).Warn("unable to read setup file")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
.ng-untouched {
|
.ng-untouched {
|
||||||
.cnsl-error {
|
.cnsl-error {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
transition: visibility .2 ease;
|
transition: visibility 0.2 ease;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,10 +24,14 @@
|
|||||||
|
|
||||||
[cnslSuffix] {
|
[cnslSuffix] {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: .5rem;
|
right: 0.5rem;
|
||||||
top: 9px;
|
top: 9px;
|
||||||
height: inherit;
|
height: inherit;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
max-width: 150px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
|
@ -48,6 +48,66 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="info-row" *ngIf="instance">
|
||||||
|
<div class="info-wrapper">
|
||||||
|
<p class="info-row-title">{{ 'IAM.PAGES.STATE' | translate }}</p>
|
||||||
|
<p
|
||||||
|
*ngIf="instance && instance.state !== undefined"
|
||||||
|
class="state"
|
||||||
|
[ngClass]="{
|
||||||
|
active: instance.state === State.INSTANCE_STATE_RUNNING,
|
||||||
|
inactive: instance.state === State.INSTANCE_STATE_STOPPED || instance.state === State.INSTANCE_STATE_STOPPING
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ 'IAM.STATE.' + instance.state | translate }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-wrapper">
|
||||||
|
<p class="info-row-title">{{ 'RESOURCEID' | translate }}</p>
|
||||||
|
<p *ngIf="instance && instance.id" class="info-row-desc">{{ instance.id }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-wrapper">
|
||||||
|
<p class="info-row-title">{{ 'NAME' | translate }}</p>
|
||||||
|
<p *ngIf="instance && instance.name" class="info-row-desc">{{ instance.name }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-wrapper">
|
||||||
|
<p class="info-row-title">{{ 'VERSION' | translate }}</p>
|
||||||
|
<p *ngIf="instance && instance.version" class="info-row-desc">{{ instance.version }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-wrapper width">
|
||||||
|
<p class="info-row-title">{{ 'IAM.PAGES.DOMAINLIST' | translate }}</p>
|
||||||
|
<div class="copy-row" *ngFor="let domain of instance?.domainsList">
|
||||||
|
<button
|
||||||
|
[disabled]="copied === domain.domain"
|
||||||
|
[matTooltip]="(copied !== domain.domain ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
|
||||||
|
cnslCopyToClipboard
|
||||||
|
[valueToCopy]="domain.domain"
|
||||||
|
(copiedValue)="copied = $event"
|
||||||
|
>
|
||||||
|
{{ domain.domain }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-wrapper">
|
||||||
|
<p class="info-row-title">{{ 'ORG.PAGES.CREATIONDATE' | translate }}</p>
|
||||||
|
<p *ngIf="instance && instance.details && instance.details.creationDate" class="info-row-desc">
|
||||||
|
{{ instance.details.creationDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-wrapper">
|
||||||
|
<p class="info-row-title">{{ 'ORG.PAGES.DATECHANGED' | translate }}</p>
|
||||||
|
<p *ngIf="instance && instance.details && instance.details.changeDate" class="info-row-desc">
|
||||||
|
{{ instance.details.changeDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="info-row" *ngIf="org">
|
<div class="info-row" *ngIf="org">
|
||||||
<div class="info-wrapper">
|
<div class="info-wrapper">
|
||||||
<p class="info-row-title">{{ 'ORG.PAGES.STATE' | translate }}</p>
|
<p class="info-row-title">{{ 'ORG.PAGES.STATE' | translate }}</p>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
import { App, AppState } from 'src/app/proto/generated/zitadel/app_pb';
|
import { App, AppState } from 'src/app/proto/generated/zitadel/app_pb';
|
||||||
import { IDP, IDPState } from 'src/app/proto/generated/zitadel/idp_pb';
|
import { IDP, IDPState } from 'src/app/proto/generated/zitadel/idp_pb';
|
||||||
|
import { InstanceDetail, State } from 'src/app/proto/generated/zitadel/instance_pb';
|
||||||
import { Org, OrgState } from 'src/app/proto/generated/zitadel/org_pb';
|
import { Org, OrgState } from 'src/app/proto/generated/zitadel/org_pb';
|
||||||
import { GrantedProject, Project, ProjectGrantState, ProjectState } from 'src/app/proto/generated/zitadel/project_pb';
|
import { GrantedProject, Project, ProjectGrantState, ProjectState } from 'src/app/proto/generated/zitadel/project_pb';
|
||||||
import { User, UserState } from 'src/app/proto/generated/zitadel/user_pb';
|
import { User, UserState } from 'src/app/proto/generated/zitadel/user_pb';
|
||||||
@ -13,12 +14,14 @@ import { User, UserState } from 'src/app/proto/generated/zitadel/user_pb';
|
|||||||
export class InfoRowComponent {
|
export class InfoRowComponent {
|
||||||
@Input() public user!: User.AsObject;
|
@Input() public user!: User.AsObject;
|
||||||
@Input() public org!: Org.AsObject;
|
@Input() public org!: Org.AsObject;
|
||||||
|
@Input() public instance!: InstanceDetail.AsObject;
|
||||||
@Input() public app!: App.AsObject;
|
@Input() public app!: App.AsObject;
|
||||||
@Input() public idp!: IDP.AsObject;
|
@Input() public idp!: IDP.AsObject;
|
||||||
@Input() public project!: Project.AsObject;
|
@Input() public project!: Project.AsObject;
|
||||||
@Input() public grantedProject!: GrantedProject.AsObject;
|
@Input() public grantedProject!: GrantedProject.AsObject;
|
||||||
|
|
||||||
public UserState: any = UserState;
|
public UserState: any = UserState;
|
||||||
|
public State: any = State;
|
||||||
public OrgState: any = OrgState;
|
public OrgState: any = OrgState;
|
||||||
public AppState: any = AppState;
|
public AppState: any = AppState;
|
||||||
public IDPState: any = IDPState;
|
public IDPState: any = IDPState;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<input cnslInput name="sid" formControlName="sid" />
|
<input cnslInput name="sid" formControlName="sid" />
|
||||||
</cnsl-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<cnsl-form-field class="sms-form-field" label="Token">
|
<cnsl-form-field *ngIf="token" class="sms-form-field" label="Token">
|
||||||
<cnsl-label>{{ 'SETTING.SMS.TWILIO.TOKEN' | translate }}</cnsl-label>
|
<cnsl-label>{{ 'SETTING.SMS.TWILIO.TOKEN' | translate }}</cnsl-label>
|
||||||
<input cnslInput name="token" formControlName="token" />
|
<input cnslInput name="token" formControlName="token" />
|
||||||
</cnsl-form-field>
|
</cnsl-form-field>
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Component, Inject } from '@angular/core';
|
import { Component, Inject } from '@angular/core';
|
||||||
import { AbstractControl, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
import { AbstractControl, FormControl, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||||
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
|
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
|
||||||
import {
|
import {
|
||||||
AddSMSProviderTwilioRequest,
|
AddSMSProviderTwilioRequest,
|
||||||
UpdateSMSProviderTwilioRequest,
|
UpdateSMSProviderTwilioRequest,
|
||||||
UpdateSMSProviderTwilioTokenRequest,
|
UpdateSMSProviderTwilioTokenRequest,
|
||||||
} from 'src/app/proto/generated/zitadel/admin_pb';
|
} from 'src/app/proto/generated/zitadel/admin_pb';
|
||||||
import { SMSProvider, TwilioConfig } from 'src/app/proto/generated/zitadel/settings_pb';
|
import { SMSProvider, TwilioConfig } from 'src/app/proto/generated/zitadel/settings_pb';
|
||||||
import { AdminService } from 'src/app/services/admin.service';
|
import { AdminService } from 'src/app/services/admin.service';
|
||||||
@ -41,13 +41,14 @@ export class DialogAddSMSProviderComponent {
|
|||||||
) {
|
) {
|
||||||
this.twilioForm = this.fb.group({
|
this.twilioForm = this.fb.group({
|
||||||
sid: ['', [Validators.required]],
|
sid: ['', [Validators.required]],
|
||||||
token: ['', [Validators.required]],
|
|
||||||
senderNumber: ['', [Validators.required]],
|
senderNumber: ['', [Validators.required]],
|
||||||
});
|
});
|
||||||
|
|
||||||
this.smsProviders = data.smsProviders;
|
this.smsProviders = data.smsProviders;
|
||||||
if (!!this.twilio) {
|
if (!!this.twilio) {
|
||||||
this.twilioForm.patchValue(this.twilio);
|
this.twilioForm.patchValue(this.twilio);
|
||||||
|
} else {
|
||||||
|
this.twilioForm.addControl('token', new FormControl('', Validators.required));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,14 +83,16 @@ export class DialogAddSMSProviderComponent {
|
|||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe((token: string) => {
|
dialogRef.afterClosed().subscribe((token: string) => {
|
||||||
if (token) {
|
if (token && this.twilioProvider?.id) {
|
||||||
const tokenReq = new UpdateSMSProviderTwilioTokenRequest();
|
const tokenReq = new UpdateSMSProviderTwilioTokenRequest();
|
||||||
tokenReq.setToken(token);
|
tokenReq.setToken(token);
|
||||||
|
tokenReq.setId(this.twilioProvider.id);
|
||||||
|
|
||||||
this.service
|
this.service
|
||||||
.updateSMSProviderTwilioToken(tokenReq)
|
.updateSMSProviderTwilioToken(tokenReq)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.toast.showInfo('SETTING.SMS.TWILIO.TOKENSET', true);
|
this.toast.showInfo('SETTING.SMS.TWILIO.TOKENSET', true);
|
||||||
|
this.dialogRef.close();
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
this.toast.showError(error);
|
this.toast.showError(error);
|
||||||
@ -110,6 +113,15 @@ export class DialogAddSMSProviderComponent {
|
|||||||
return this.twilioForm.get('sid');
|
return this.twilioForm.get('sid');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get twilioProvider(): SMSProvider.AsObject | undefined {
|
||||||
|
const twilioProvider: SMSProvider.AsObject | undefined = this.smsProviders.find((p) => p.twilio);
|
||||||
|
if (twilioProvider) {
|
||||||
|
return twilioProvider;
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public get twilio(): TwilioConfig.AsObject | undefined {
|
public get twilio(): TwilioConfig.AsObject | undefined {
|
||||||
const twilioProvider: SMSProvider.AsObject | undefined = this.smsProviders.find((p) => p.twilio);
|
const twilioProvider: SMSProvider.AsObject | undefined = this.smsProviders.find((p) => p.twilio);
|
||||||
if (twilioProvider && !!twilioProvider.twilio) {
|
if (twilioProvider && !!twilioProvider.twilio) {
|
||||||
|
@ -75,9 +75,32 @@
|
|||||||
active: twilio?.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_ACTIVE,
|
active: twilio?.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_ACTIVE,
|
||||||
inactive: twilio?.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_INACTIVE
|
inactive: twilio?.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_INACTIVE
|
||||||
}"
|
}"
|
||||||
></span>
|
>{{ 'SETTING.SMS.SMSPROVIDERSTATE.' + twilio?.state | translate }}</span
|
||||||
|
>
|
||||||
|
|
||||||
<span class="fill-space"></span>
|
<span class="fill-space"></span>
|
||||||
|
<button
|
||||||
|
*ngIf="twilio && twilio.id"
|
||||||
|
[disabled]="(['iam.write'] | hasRole | async) === false"
|
||||||
|
mat-stroked-button
|
||||||
|
(click)="toggleSMSProviderState(twilio.id)"
|
||||||
|
>
|
||||||
|
<span *ngIf="twilio.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_ACTIVE">{{
|
||||||
|
'ACTIONS.DEACTIVATE' | translate
|
||||||
|
}}</span>
|
||||||
|
<span *ngIf="twilio.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_INACTIVE">{{
|
||||||
|
'ACTIONS.ACTIVATE' | translate
|
||||||
|
}}</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
*ngIf="twilio && twilio.id"
|
||||||
|
color="warn"
|
||||||
|
[disabled]="(['iam.write'] | hasRole | async) === false"
|
||||||
|
mat-icon-button
|
||||||
|
(click)="removeSMSProvider(twilio.id)"
|
||||||
|
>
|
||||||
|
<i class="las la-trash"></i>
|
||||||
|
</button>
|
||||||
<button [disabled]="(['iam.write'] | hasRole | async) === false" mat-icon-button (click)="editSMSProvider()">
|
<button [disabled]="(['iam.write'] | hasRole | async) === false" mat-icon-button (click)="editSMSProvider()">
|
||||||
<i class="las la-pen"></i>
|
<i class="las la-pen"></i>
|
||||||
</button>
|
</button>
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
width: 350px;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
@ -3,12 +3,12 @@ import { AbstractControl, UntypedFormBuilder, UntypedFormGroup, Validators } fro
|
|||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { take } from 'rxjs';
|
import { take } from 'rxjs';
|
||||||
import {
|
import {
|
||||||
AddSMSProviderTwilioRequest,
|
AddSMSProviderTwilioRequest,
|
||||||
AddSMTPConfigRequest,
|
AddSMTPConfigRequest,
|
||||||
UpdateSMSProviderTwilioRequest,
|
UpdateSMSProviderTwilioRequest,
|
||||||
UpdateSMTPConfigPasswordRequest,
|
UpdateSMTPConfigPasswordRequest,
|
||||||
UpdateSMTPConfigPasswordResponse,
|
UpdateSMTPConfigPasswordResponse,
|
||||||
UpdateSMTPConfigRequest,
|
UpdateSMTPConfigRequest,
|
||||||
} from 'src/app/proto/generated/zitadel/admin_pb';
|
} from 'src/app/proto/generated/zitadel/admin_pb';
|
||||||
import { DebugNotificationProvider, SMSProvider, SMSProviderConfigState } from 'src/app/proto/generated/zitadel/settings_pb';
|
import { DebugNotificationProvider, SMSProvider, SMSProviderConfigState } from 'src/app/proto/generated/zitadel/settings_pb';
|
||||||
import { AdminService } from 'src/app/services/admin.service';
|
import { AdminService } from 'src/app/services/admin.service';
|
||||||
@ -16,6 +16,7 @@ import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
|||||||
import { ToastService } from 'src/app/services/toast.service';
|
import { ToastService } from 'src/app/services/toast.service';
|
||||||
|
|
||||||
import { InfoSectionType } from '../../info-section/info-section.component';
|
import { InfoSectionType } from '../../info-section/info-section.component';
|
||||||
|
import { WarnDialogComponent } from '../../warn-dialog/warn-dialog.component';
|
||||||
import { PolicyComponentServiceType } from '../policy-component-types.enum';
|
import { PolicyComponentServiceType } from '../policy-component-types.enum';
|
||||||
import { DialogAddSMSProviderComponent } from './dialog-add-sms-provider/dialog-add-sms-provider.component';
|
import { DialogAddSMSProviderComponent } from './dialog-add-sms-provider/dialog-add-sms-provider.component';
|
||||||
import { PasswordDialogComponent } from './password-dialog/password-dialog.component';
|
import { PasswordDialogComponent } from './password-dialog/password-dialog.component';
|
||||||
@ -185,11 +186,12 @@ export class NotificationSettingsComponent implements OnInit {
|
|||||||
|
|
||||||
dialogRef.afterClosed().subscribe((req: AddSMSProviderTwilioRequest | UpdateSMSProviderTwilioRequest) => {
|
dialogRef.afterClosed().subscribe((req: AddSMSProviderTwilioRequest | UpdateSMSProviderTwilioRequest) => {
|
||||||
if (req) {
|
if (req) {
|
||||||
if (this.hasTwilio) {
|
if (!!this.twilio) {
|
||||||
this.service
|
this.service
|
||||||
.updateSMSProviderTwilio(req as UpdateSMSProviderTwilioRequest)
|
.updateSMSProviderTwilio(req as UpdateSMSProviderTwilioRequest)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.toast.showInfo('SETTING.SMS.TWILIO.ADDED', true);
|
this.toast.showInfo('SETTING.SMS.TWILIO.ADDED', true);
|
||||||
|
this.fetchData();
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
this.toast.showError(error);
|
this.toast.showError(error);
|
||||||
@ -199,6 +201,7 @@ export class NotificationSettingsComponent implements OnInit {
|
|||||||
.addSMSProviderTwilio(req as AddSMSProviderTwilioRequest)
|
.addSMSProviderTwilio(req as AddSMSProviderTwilioRequest)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.toast.showInfo('SETTING.SMS.TWILIO.ADDED', true);
|
this.toast.showInfo('SETTING.SMS.TWILIO.ADDED', true);
|
||||||
|
this.fetchData();
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
this.toast.showError(error);
|
this.toast.showError(error);
|
||||||
@ -234,6 +237,59 @@ export class NotificationSettingsComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public toggleSMSProviderState(id: string): void {
|
||||||
|
const provider = this.smsProviders.find((p) => p.id === id);
|
||||||
|
if (provider) {
|
||||||
|
if (provider.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_ACTIVE) {
|
||||||
|
this.service
|
||||||
|
.deactivateSMSProvider(id)
|
||||||
|
.then(() => {
|
||||||
|
this.toast.showInfo('SETTING.SMS.DEACTIVATED', true);
|
||||||
|
this.fetchData();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
|
} else if (provider.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_INACTIVE) {
|
||||||
|
this.service
|
||||||
|
.activateSMSProvider(id)
|
||||||
|
.then(() => {
|
||||||
|
this.toast.showInfo('SETTING.SMS.ACTIVATED', true);
|
||||||
|
this.fetchData();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeSMSProvider(id: string): void {
|
||||||
|
const dialogRef = this.dialog.open(WarnDialogComponent, {
|
||||||
|
data: {
|
||||||
|
confirmKey: 'ACTIONS.DELETE',
|
||||||
|
cancelKey: 'ACTIONS.CANCEL',
|
||||||
|
titleKey: 'SETTING.SMS.REMOVEPROVIDER',
|
||||||
|
descriptionKey: 'SETTING.SMS.REMOVEPROVIDER_DESC',
|
||||||
|
},
|
||||||
|
width: '400px',
|
||||||
|
});
|
||||||
|
|
||||||
|
dialogRef.afterClosed().subscribe((resp) => {
|
||||||
|
if (resp) {
|
||||||
|
this.service
|
||||||
|
.removeSMSProvider(id)
|
||||||
|
.then(() => {
|
||||||
|
this.toast.showInfo('SETTING.SMS.TWILIO.REMOVED', true);
|
||||||
|
this.fetchData();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public get twilio(): SMSProvider.AsObject | undefined {
|
public get twilio(): SMSProvider.AsObject | undefined {
|
||||||
return this.smsProviders.find((p) => p.twilio);
|
return this.smsProviders.find((p) => p.twilio);
|
||||||
}
|
}
|
||||||
@ -257,13 +313,4 @@ export class NotificationSettingsComponent implements OnInit {
|
|||||||
public get host(): AbstractControl | null {
|
public get host(): AbstractControl | null {
|
||||||
return this.form.get('host');
|
return this.form.get('host');
|
||||||
}
|
}
|
||||||
|
|
||||||
public get hasTwilio(): boolean {
|
|
||||||
const twilioProvider: SMSProvider.AsObject | undefined = this.smsProviders.find((p) => p.twilio);
|
|
||||||
if (twilioProvider && !!twilioProvider.twilio) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import { CardModule } from '../../card/card.module';
|
|||||||
import { FormFieldModule } from '../../form-field/form-field.module';
|
import { FormFieldModule } from '../../form-field/form-field.module';
|
||||||
import { InfoSectionModule } from '../../info-section/info-section.module';
|
import { InfoSectionModule } from '../../info-section/info-section.module';
|
||||||
import { InputModule } from '../../input/input.module';
|
import { InputModule } from '../../input/input.module';
|
||||||
|
import { WarnDialogModule } from '../../warn-dialog/warn-dialog.module';
|
||||||
import { DialogAddSMSProviderComponent } from './dialog-add-sms-provider/dialog-add-sms-provider.component';
|
import { DialogAddSMSProviderComponent } from './dialog-add-sms-provider/dialog-add-sms-provider.component';
|
||||||
import { NotificationSettingsComponent } from './notification-settings.component';
|
import { NotificationSettingsComponent } from './notification-settings.component';
|
||||||
import { PasswordDialogComponent } from './password-dialog/password-dialog.component';
|
import { PasswordDialogComponent } from './password-dialog/password-dialog.component';
|
||||||
@ -31,6 +32,7 @@ import { PasswordDialogComponent } from './password-dialog/password-dialog.compo
|
|||||||
InputModule,
|
InputModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
FormFieldModule,
|
FormFieldModule,
|
||||||
|
WarnDialogModule,
|
||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
|
@ -1,22 +1,28 @@
|
|||||||
<cnsl-refresh-table [hideRefresh]="true" [loading]="loading$ | async" (refreshed)="refreshPage()"
|
<cnsl-refresh-table
|
||||||
[dataSize]="dataSource?.data?.length ?? 0" [timestamp]="actionsResult?.details?.viewTimestamp"
|
[hideRefresh]="true"
|
||||||
[selection]="selection">
|
[loading]="loading$ | async"
|
||||||
|
(refreshed)="refreshPage()"
|
||||||
|
[dataSize]="dataSource?.data?.length ?? 0"
|
||||||
|
[timestamp]="actionsResult?.details?.viewTimestamp"
|
||||||
|
[selection]="selection"
|
||||||
|
>
|
||||||
<div actions *ngIf="selection.isEmpty()">
|
<div actions *ngIf="selection.isEmpty()">
|
||||||
<a class="cnsl-action-button" color="primary" mat-raised-button (click)="openAddAction()">
|
<a class="cnsl-action-button" color="primary" mat-raised-button (click)="openAddAction()">
|
||||||
<mat-icon class="icon">add</mat-icon>{{ 'ACTIONS.NEW' | translate }}
|
<mat-icon class="icon">add</mat-icon>{{ 'ACTIONS.NEW' | translate }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div actions *ngIf="!selection.isEmpty()">
|
<div actions *ngIf="!selection.isEmpty()">
|
||||||
<button class="margin-right action-state-btn cnsl-action-button bg-state inactive" mat-raised-button
|
<button
|
||||||
(click)="deactivateSelection()">
|
class="margin-right action-state-btn cnsl-action-button bg-state inactive"
|
||||||
|
mat-raised-button
|
||||||
|
(click)="deactivateSelection()"
|
||||||
|
>
|
||||||
<span>{{ 'ACTIONS.DEACTIVATE' | translate }}</span>
|
<span>{{ 'ACTIONS.DEACTIVATE' | translate }}</span>
|
||||||
<cnsl-action-keys (actionTriggered)="deactivateSelection()" [type]="ActionKeysType.DEACTIVATE">
|
<cnsl-action-keys (actionTriggered)="deactivateSelection()" [type]="ActionKeysType.DEACTIVATE"> </cnsl-action-keys>
|
||||||
</cnsl-action-keys>
|
|
||||||
</button>
|
</button>
|
||||||
<button class="action-state-btn cnsl-action-button bg-state active" mat-raised-button (click)="activateSelection()">
|
<button class="action-state-btn cnsl-action-button bg-state active" mat-raised-button (click)="activateSelection()">
|
||||||
<span>{{ 'ACTIONS.REACTIVATE' | translate }}</span>
|
<span>{{ 'ACTIONS.REACTIVATE' | translate }}</span>
|
||||||
<cnsl-action-keys (actionTriggered)="activateSelection()" [type]="ActionKeysType.REACTIVATE">
|
<cnsl-action-keys (actionTriggered)="activateSelection()" [type]="ActionKeysType.REACTIVATE"> </cnsl-action-keys>
|
||||||
</cnsl-action-keys>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -24,48 +30,61 @@
|
|||||||
<table class="table" mat-table [dataSource]="dataSource">
|
<table class="table" mat-table [dataSource]="dataSource">
|
||||||
<ng-container matColumnDef="select">
|
<ng-container matColumnDef="select">
|
||||||
<th mat-header-cell *matHeaderCellDef class="action-select-cell">
|
<th mat-header-cell *matHeaderCellDef class="action-select-cell">
|
||||||
<mat-checkbox color="primary" (change)="$event ? masterToggle() : null"
|
<mat-checkbox
|
||||||
|
color="primary"
|
||||||
|
(change)="$event ? masterToggle() : null"
|
||||||
[checked]="selection.hasValue() && isAllSelected()"
|
[checked]="selection.hasValue() && isAllSelected()"
|
||||||
[indeterminate]="selection.hasValue() && !isAllSelected()">
|
[indeterminate]="selection.hasValue() && !isAllSelected()"
|
||||||
|
>
|
||||||
</mat-checkbox>
|
</mat-checkbox>
|
||||||
</th>
|
</th>
|
||||||
<td mat-cell *matCellDef="let key" class="action-select-cell">
|
<td mat-cell *matCellDef="let key" class="action-select-cell">
|
||||||
<mat-checkbox color="primary" (click)="$event.stopPropagation()"
|
<mat-checkbox
|
||||||
(change)="$event ? selection.toggle(key) : null" [checked]="selection.isSelected(key)">
|
color="primary"
|
||||||
|
(click)="$event.stopPropagation()"
|
||||||
|
(change)="$event ? selection.toggle(key) : null"
|
||||||
|
[checked]="selection.isSelected(key)"
|
||||||
|
>
|
||||||
</mat-checkbox>
|
</mat-checkbox>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="id">
|
<ng-container matColumnDef="id">
|
||||||
<th mat-header-cell *matHeaderCellDef> {{ 'FLOWS.ID' | translate }} </th>
|
<th mat-header-cell *matHeaderCellDef>{{ 'FLOWS.ID' | translate }}</th>
|
||||||
<td mat-cell *matCellDef="let action" class="pointer"> {{ action?.id }} </td>
|
<td mat-cell *matCellDef="let action" class="pointer">{{ action?.id }}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="name">
|
<ng-container matColumnDef="name">
|
||||||
<th mat-header-cell *matHeaderCellDef> {{ 'FLOWS.NAME' | translate }} </th>
|
<th mat-header-cell *matHeaderCellDef>{{ 'FLOWS.NAME' | translate }}</th>
|
||||||
<td mat-cell *matCellDef="let action" class="pointer"> {{ action?.name }} </td>
|
<td mat-cell *matCellDef="let action" class="pointer">{{ action?.name }}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="state">
|
<ng-container matColumnDef="state">
|
||||||
<th mat-header-cell *matHeaderCellDef> {{ 'FLOWS.STATE' | translate }} </th>
|
<th mat-header-cell *matHeaderCellDef>{{ 'FLOWS.STATE' | translate }}</th>
|
||||||
<td mat-cell *matCellDef="let action" class="pointer">
|
<td mat-cell *matCellDef="let action" class="pointer">
|
||||||
<span class="state"
|
<span
|
||||||
[ngClass]="{'active': action.state === ActionState.ACTION_STATE_ACTIVE,'inactive': action.state === ActionState.ACTION_STATE_INACTIVE }">
|
class="state"
|
||||||
{{'FLOWS.STATES.'+action.state | translate}}</span>
|
[ngClass]="{
|
||||||
|
active: action.state === ActionState.ACTION_STATE_ACTIVE,
|
||||||
|
inactive: action.state === ActionState.ACTION_STATE_INACTIVE
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ 'FLOWS.STATES.' + action.state | translate }}</span
|
||||||
|
>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="timeout">
|
<ng-container matColumnDef="timeout">
|
||||||
<th mat-header-cell *matHeaderCellDef> {{ 'FLOWS.TIMEOUT' | translate }} </th>
|
<th mat-header-cell *matHeaderCellDef>{{ 'FLOWS.TIMEOUT' | translate }}</th>
|
||||||
<td mat-cell *matCellDef="let key" class="pointer">
|
<td mat-cell *matCellDef="let key" class="pointer">
|
||||||
{{key.timeout | durationToSeconds}}
|
{{ key.timeout | durationToSeconds }}
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="allowedToFail">
|
<ng-container matColumnDef="allowedToFail">
|
||||||
<th mat-header-cell *matHeaderCellDef> {{ 'FLOWS.ALLOWEDTOFAIL' | translate }} </th>
|
<th mat-header-cell *matHeaderCellDef>{{ 'FLOWS.ALLOWEDTOFAIL' | translate }}</th>
|
||||||
<td mat-cell *matCellDef="let action" class="pointer">
|
<td mat-cell *matCellDef="let action" class="pointer">
|
||||||
{{action.allowedToFail}}
|
{{ action.allowedToFail }}
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
@ -73,8 +92,14 @@
|
|||||||
<th mat-header-cell *matHeaderCellDef></th>
|
<th mat-header-cell *matHeaderCellDef></th>
|
||||||
<td mat-cell *matCellDef="let action" class="pointer">
|
<td mat-cell *matCellDef="let action" class="pointer">
|
||||||
<cnsl-table-actions>
|
<cnsl-table-actions>
|
||||||
<button [disabled]="(['action.write'] | hasRole | async) === false" actions
|
<button
|
||||||
matTooltip="{{'ACTIONS.REMOVE' | translate}}" color="warn" (click)="deleteAction(action)" mat-icon-button>
|
[disabled]="(['action.write'] | hasRole | async) === false"
|
||||||
|
actions
|
||||||
|
matTooltip="{{ 'ACTIONS.REMOVE' | translate }}"
|
||||||
|
color="warn"
|
||||||
|
(click)="$event.stopPropagation(); deleteAction(action)"
|
||||||
|
mat-icon-button
|
||||||
|
>
|
||||||
<i class="las la-trash"></i>
|
<i class="las la-trash"></i>
|
||||||
</button>
|
</button>
|
||||||
</cnsl-table-actions>
|
</cnsl-table-actions>
|
||||||
@ -82,12 +107,17 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
<tr class="highlight" mat-row *matRowDef="let action; columns: displayedColumns;" (click)="openDialog(action)">
|
<tr class="highlight" mat-row *matRowDef="let action; columns: displayedColumns" (click)="openDialog(action)"></tr>
|
||||||
</tr>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<cnsl-paginator #paginator class="paginator" [timestamp]="actionsResult?.details?.viewTimestamp"
|
<cnsl-paginator
|
||||||
[length]="actionsResult?.details?.totalResult || 0" [pageSize]="20" [pageSizeOptions]="[10, 20, 50, 100]"
|
#paginator
|
||||||
(page)="changePage($event)"></cnsl-paginator>
|
class="paginator"
|
||||||
</cnsl-refresh-table>
|
[timestamp]="actionsResult?.details?.viewTimestamp"
|
||||||
|
[length]="actionsResult?.details?.totalResult || 0"
|
||||||
|
[pageSize]="20"
|
||||||
|
[pageSizeOptions]="[10, 20, 50, 100]"
|
||||||
|
(page)="changePage($event)"
|
||||||
|
></cnsl-paginator>
|
||||||
|
</cnsl-refresh-table>
|
||||||
|
@ -1,32 +1,33 @@
|
|||||||
<div class="iam-top">
|
<cnsl-top-view
|
||||||
<div class="max-width-container">
|
[hasBackButton]="false"
|
||||||
<div class="iam-top-row">
|
title="{{ 'IAM.TITLE' | translate }}"
|
||||||
<div>
|
sub="{{ 'IAM.DESCRIPTION' | translate }}"
|
||||||
<div class="iam-title-row">
|
[isActive]="instance?.state === State.STATE_RUNNING"
|
||||||
<h1 class="iam-title">{{ 'IAM.TITLE' | translate }}</h1>
|
[isInactive]="instance?.state === State.STATE_STOPPED || instance?.state === State.STATE_STOPPING"
|
||||||
</div>
|
[hasContributors]="true"
|
||||||
<p class="iam-sub cnsl-secondary-text">{{ 'IAM.DESCRIPTION' | translate }}</p>
|
stateTooltip="{{ 'INSTANCE.STATE.' + instance?.state | translate }}"
|
||||||
</div>
|
>
|
||||||
<span class="fill-space"></span>
|
<cnsl-contributors
|
||||||
<cnsl-contributors
|
topContributors
|
||||||
[totalResult]="totalMemberResult"
|
[totalResult]="totalMemberResult"
|
||||||
[loading]="loading$ | async"
|
[loading]="loading$ | async"
|
||||||
[membersSubject]="membersSubject"
|
[membersSubject]="membersSubject"
|
||||||
title="{{ 'PROJECT.MEMBER.TITLE' | translate }}"
|
title="{{ 'PROJECT.MEMBER.TITLE' | translate }}"
|
||||||
description="{{ 'PROJECT.MEMBER.TITLEDESC' | translate }}"
|
description="{{ 'PROJECT.MEMBER.TITLEDESC' | translate }}"
|
||||||
(addClicked)="openAddMember()"
|
(addClicked)="openAddMember()"
|
||||||
(showDetailClicked)="showDetail()"
|
(showDetailClicked)="showDetail()"
|
||||||
(refreshClicked)="loadMembers()"
|
(refreshClicked)="loadMembers()"
|
||||||
[disabled]="(['iam.member.write'] | hasRole | async) === false"
|
[disabled]="(['iam.member.write'] | hasRole | async) === false"
|
||||||
>
|
>
|
||||||
</cnsl-contributors>
|
</cnsl-contributors>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="max-width-container">
|
|
||||||
<h2 class="org-table-title">{{ 'ORG.LIST.TITLE' | translate }}</h2>
|
|
||||||
|
|
||||||
<p class="org-table-desc cnsl-secondary-text">{{ 'ORG.LIST.DESCRIPTION' | translate }}</p>
|
<cnsl-info-row topContent *ngIf="instance" [instance]="instance"></cnsl-info-row>
|
||||||
|
</cnsl-top-view>
|
||||||
|
|
||||||
|
<div class="max-width-container">
|
||||||
|
<h2 class="instance-table-title">{{ 'ORG.LIST.TITLE' | translate }}</h2>
|
||||||
|
|
||||||
|
<p class="instance-table-desc cnsl-secondary-text">{{ 'ORG.LIST.DESCRIPTION' | translate }}</p>
|
||||||
|
|
||||||
<cnsl-org-table></cnsl-org-table>
|
<cnsl-org-table></cnsl-org-table>
|
||||||
|
|
||||||
|
@ -4,55 +4,15 @@
|
|||||||
$foreground: map-get($theme, foreground);
|
$foreground: map-get($theme, foreground);
|
||||||
$is-dark-theme: map-get($theme, is-dark);
|
$is-dark-theme: map-get($theme, is-dark);
|
||||||
$background: map-get($theme, background);
|
$background: map-get($theme, background);
|
||||||
|
|
||||||
.iam-top {
|
|
||||||
border-bottom: 1px solid map-get($foreground, divider);
|
|
||||||
margin: 0 -2rem;
|
|
||||||
padding: 2rem 2rem 1rem 2rem;
|
|
||||||
background: map-get($background, metadata-section);
|
|
||||||
|
|
||||||
@media only screen and (max-width: 500px) {
|
|
||||||
margin: 0 -1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.iam-top-row {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding-bottom: 1rem;
|
|
||||||
|
|
||||||
.iam-title-row {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.iam-title {
|
|
||||||
margin: 0;
|
|
||||||
margin-right: 0.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.iam-sub {
|
|
||||||
margin: 1rem 0 0 0;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.iam-top-desc {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fill-space {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.org-table-title {
|
.instance-table-title {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.org-table-desc {
|
.instance-table-desc {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import { BehaviorSubject, from, Observable, of } from 'rxjs';
|
|||||||
import { catchError, finalize, map } from 'rxjs/operators';
|
import { catchError, finalize, map } from 'rxjs/operators';
|
||||||
import { CreationType, MemberCreateDialogComponent } from 'src/app/modules/add-member-dialog/member-create-dialog.component';
|
import { CreationType, MemberCreateDialogComponent } from 'src/app/modules/add-member-dialog/member-create-dialog.component';
|
||||||
import { PolicyComponentServiceType } from 'src/app/modules/policies/policy-component-types.enum';
|
import { PolicyComponentServiceType } from 'src/app/modules/policies/policy-component-types.enum';
|
||||||
|
import { InstanceDetail, State } from 'src/app/proto/generated/zitadel/instance_pb';
|
||||||
import { Member } from 'src/app/proto/generated/zitadel/member_pb';
|
import { Member } from 'src/app/proto/generated/zitadel/member_pb';
|
||||||
import { User } from 'src/app/proto/generated/zitadel/user_pb';
|
import { User } from 'src/app/proto/generated/zitadel/user_pb';
|
||||||
import { AdminService } from 'src/app/services/admin.service';
|
import { AdminService } from 'src/app/services/admin.service';
|
||||||
@ -17,12 +18,13 @@ import { ToastService } from 'src/app/services/toast.service';
|
|||||||
styleUrls: ['./instance.component.scss'],
|
styleUrls: ['./instance.component.scss'],
|
||||||
})
|
})
|
||||||
export class InstanceComponent {
|
export class InstanceComponent {
|
||||||
|
public instance!: InstanceDetail.AsObject;
|
||||||
public PolicyComponentServiceType: any = PolicyComponentServiceType;
|
public PolicyComponentServiceType: any = PolicyComponentServiceType;
|
||||||
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||||
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
|
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
|
||||||
public totalMemberResult: number = 0;
|
public totalMemberResult: number = 0;
|
||||||
public membersSubject: BehaviorSubject<Member.AsObject[]> = new BehaviorSubject<Member.AsObject[]>([]);
|
public membersSubject: BehaviorSubject<Member.AsObject[]> = new BehaviorSubject<Member.AsObject[]>([]);
|
||||||
|
public State: any = State;
|
||||||
constructor(
|
constructor(
|
||||||
public adminService: AdminService,
|
public adminService: AdminService,
|
||||||
private dialog: MatDialog,
|
private dialog: MatDialog,
|
||||||
@ -39,6 +41,17 @@ export class InstanceComponent {
|
|||||||
});
|
});
|
||||||
|
|
||||||
breadcrumbService.setBreadcrumb([instanceBread]);
|
breadcrumbService.setBreadcrumb([instanceBread]);
|
||||||
|
|
||||||
|
this.adminService
|
||||||
|
.getMyInstance()
|
||||||
|
.then((instanceResp) => {
|
||||||
|
if (instanceResp.instance) {
|
||||||
|
this.instance = instanceResp.instance;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public loadMembers(): void {
|
public loadMembers(): void {
|
||||||
|
@ -16,12 +16,14 @@ import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
|||||||
import { CardModule } from 'src/app/modules/card/card.module';
|
import { CardModule } from 'src/app/modules/card/card.module';
|
||||||
import { ChangesModule } from 'src/app/modules/changes/changes.module';
|
import { ChangesModule } from 'src/app/modules/changes/changes.module';
|
||||||
import { ContributorsModule } from 'src/app/modules/contributors/contributors.module';
|
import { ContributorsModule } from 'src/app/modules/contributors/contributors.module';
|
||||||
|
import { InfoRowModule } from 'src/app/modules/info-row/info-row.module';
|
||||||
import { InputModule } from 'src/app/modules/input/input.module';
|
import { InputModule } from 'src/app/modules/input/input.module';
|
||||||
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
||||||
import { OrgTableModule } from 'src/app/modules/org-table/org-table.module';
|
import { OrgTableModule } from 'src/app/modules/org-table/org-table.module';
|
||||||
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
|
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
|
||||||
import { SettingsGridModule } from 'src/app/modules/settings-grid/settings-grid.module';
|
import { SettingsGridModule } from 'src/app/modules/settings-grid/settings-grid.module';
|
||||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||||
|
import { TopViewModule } from 'src/app/modules/top-view/top-view.module';
|
||||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
||||||
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
|
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
|
||||||
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
|
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
|
||||||
@ -43,7 +45,9 @@ import { InstanceComponent } from './instance.component';
|
|||||||
MatCheckboxModule,
|
MatCheckboxModule,
|
||||||
MetaLayoutModule,
|
MetaLayoutModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
|
TopViewModule,
|
||||||
MatTableModule,
|
MatTableModule,
|
||||||
|
InfoRowModule,
|
||||||
InputModule,
|
InputModule,
|
||||||
MatSortModule,
|
MatSortModule,
|
||||||
MatTooltipModule,
|
MatTooltipModule,
|
||||||
|
@ -1,33 +1,53 @@
|
|||||||
<h1 mat-dialog-title>
|
<h1 mat-dialog-title>
|
||||||
<span class="title">{{'APP.OIDC.CLIENTSECRET' | translate}}</span>
|
<span class="title">{{ 'APP.OIDC.CLIENTSECRET' | translate }}</span>
|
||||||
</h1>
|
</h1>
|
||||||
<p class="desc cnsl-secondary-text">{{'APP.OIDC.CLIENTSECRET_DESCRIPTION' | translate}}</p>
|
<p class="desc cnsl-secondary-text">{{ 'APP.OIDC.CLIENTSECRET_DESCRIPTION' | translate }}</p>
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
<div class="flex" *ngIf="data.clientId">
|
<div class="flex" *ngIf="data.clientId">
|
||||||
<span class="overflow-auto"><span class="desc">ClientId:</span> {{data.clientId}}</span>
|
<span class="overflow-auto"><span class="desc">ClientId:</span> {{ data.clientId }}</span>
|
||||||
<button color="primary" [disabled]="copied === data.clientId" matTooltip="copy to clipboard" cnslCopyToClipboard
|
<button
|
||||||
[valueToCopy]="data.clientId" (copiedValue)="this.copied = $event" mat-icon-button>
|
color="primary"
|
||||||
|
[disabled]="copied === data.clientId"
|
||||||
|
matTooltip="copy to clipboard"
|
||||||
|
cnslCopyToClipboard
|
||||||
|
[valueToCopy]="data.clientId"
|
||||||
|
(copiedValue)="this.copied = $event"
|
||||||
|
mat-icon-button
|
||||||
|
>
|
||||||
<i *ngIf="copied !== data.clientId" class="las la-clipboard"></i>
|
<i *ngIf="copied !== data.clientId" class="las la-clipboard"></i>
|
||||||
<i *ngIf="copied === data.clientId" class="las la-clipboard-check"></i>
|
<i *ngIf="copied === data.clientId" class="las la-clipboard-check"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="data.clientSecret; else showNoSecretInfo" class="flex">
|
<div *ngIf="data.clientSecret; else showNoSecretInfo" class="flex">
|
||||||
<span class="overflow-auto"><span class="desc cnsl-secondary-text">ClientSecret:</span> {{data.clientSecret}}</span>
|
<span class="overflow-auto"><span class="desc cnsl-secondary-text">ClientSecret:</span> {{ data.clientSecret }}</span>
|
||||||
<button color="primary" [disabled]="copied === data.clientSecret" matTooltip="copy to clipboard" cnslCopyToClipboard
|
<button
|
||||||
[valueToCopy]="data.clientSecret" (copiedValue)="this.copied = $event" mat-icon-button>
|
color="primary"
|
||||||
|
[disabled]="copied === data.clientSecret"
|
||||||
|
matTooltip="copy to clipboard"
|
||||||
|
cnslCopyToClipboard
|
||||||
|
[valueToCopy]="data.clientSecret"
|
||||||
|
(copiedValue)="this.copied = $event"
|
||||||
|
mat-icon-button
|
||||||
|
>
|
||||||
<i *ngIf="copied !== data.clientSecret" class="las la-clipboard"></i>
|
<i *ngIf="copied !== data.clientSecret" class="las la-clipboard"></i>
|
||||||
<i *ngIf="copied === data.clientSecret" class="las la-clipboard-check"></i>
|
<i *ngIf="copied === data.clientSecret" class="las la-clipboard-check"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ng-template #showNoSecretInfo>
|
<ng-template #showNoSecretInfo>
|
||||||
<cnsl-info-section>{{'APP.OIDC.CLIENTSECRET_NOSECRET' | translate}}</cnsl-info-section>
|
<cnsl-info-section>{{ 'APP.OIDC.CLIENTSECRET_NOSECRET' | translate }}</cnsl-info-section>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</div>
|
</div>
|
||||||
<div mat-dialog-actions class="action">
|
<div mat-dialog-actions class="action">
|
||||||
<button cdkFocusInitial color="primary" mat-raised-button class="ok-button" (click)="closeDialog()"
|
<button
|
||||||
[attr.data-e2e]="'close-dialog'">
|
cdkFocusInitial
|
||||||
{{'ACTIONS.CLOSE' | translate}}
|
color="primary"
|
||||||
|
mat-raised-button
|
||||||
|
class="ok-button"
|
||||||
|
(click)="closeDialog()"
|
||||||
|
[attr.data-e2e]="'close-dialog'"
|
||||||
|
>
|
||||||
|
{{ 'ACTIONS.CLOSE' | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<div class="signed-out-wrap">
|
<div class="signed-out-wrap">
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<div class="signed-out-header">
|
<div class="signed-out-header">
|
||||||
<img alt="zitadel logo" *ngIf="dark; else lighttheme" src="../../../assets/images/zitadel-logo-light.svg" />
|
<img alt="zitadel logo" *ngIf="dark; else lighttheme" src="./assets/images/zitadel-logo-light.svg" />
|
||||||
<ng-template #lighttheme>
|
<ng-template #lighttheme>
|
||||||
<img alt="zitadel logo" src="../../../assets/images/zitadel-logo-dark.svg" />
|
<img alt="zitadel logo" src="./assets/images/zitadel-logo-dark.svg" />
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<p class="cnsl-secondary-text">{{ 'USER.SIGNEDOUT' | translate }}</p>
|
<p class="cnsl-secondary-text">{{ 'USER.SIGNEDOUT' | translate }}</p>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.user-create-main-content {
|
.user-create-main-content {
|
||||||
max-width: 35rem;
|
max-width: 45rem;
|
||||||
|
|
||||||
@media only screen and (max-width: 500px) {
|
@media only screen and (max-width: 500px) {
|
||||||
padding: 0 0.5rem;
|
padding: 0 0.5rem;
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
<h1 mat-dialog-title>
|
<h1 mat-dialog-title>
|
||||||
<span class="title">{{'USER.MFA.DIALOG.ADD_MFA_TITLE' | translate}} {{data?.number}}</span>
|
<span class="title">{{ 'USER.MFA.DIALOG.ADD_MFA_TITLE' | translate }} {{ data?.number }}</span>
|
||||||
</h1>
|
</h1>
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
<ng-container *ngIf="selectedType === undefined">
|
<ng-container *ngIf="selectedType === undefined">
|
||||||
<p class="desc cnsl-secondary-text">{{'USER.MFA.DIALOG.ADD_MFA_DESCRIPTION' | translate}}</p>
|
<p class="desc cnsl-secondary-text">{{ 'USER.MFA.DIALOG.ADD_MFA_DESCRIPTION' | translate }}</p>
|
||||||
|
|
||||||
<div class="type-selection">
|
<div class="type-selection">
|
||||||
<button mat-raised-button color="primary" [disabled]="data.otpDisabled" (click)="selectType(AuthFactorType.OTP)">
|
<button mat-raised-button color="primary" [disabled]="data.otpDisabled" (click)="selectType(AuthFactorType.OTP)">
|
||||||
<div class="otp-btn">
|
<div class="otp-btn">
|
||||||
<mat-icon class="icon" svgIcon="mdi_radar"></mat-icon>
|
<mat-icon class="icon" svgIcon="mdi_radar"></mat-icon>
|
||||||
<span>{{'USER.MFA.OTP' | translate}}</span>
|
<span>{{ 'USER.MFA.OTP' | translate }}</span>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
<button mat-raised-button color="primary" (click)="selectType(AuthFactorType.U2F)">
|
<button mat-raised-button color="primary" (click)="selectType(AuthFactorType.U2F)">
|
||||||
@ -19,17 +19,33 @@
|
|||||||
<i matTooltip="Security Key" class="lab la-usb"></i>
|
<i matTooltip="Security Key" class="lab la-usb"></i>
|
||||||
<mat-icon matTooltip="NFC">nfc</mat-icon>
|
<mat-icon matTooltip="NFC">nfc</mat-icon>
|
||||||
</div>
|
</div>
|
||||||
<span>{{'USER.MFA.U2F' | translate}}</span>
|
<span>{{ 'USER.MFA.U2F' | translate }}</span>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<div class="otp" *ngIf="selectedType === AuthFactorType.OTP">
|
<div class="otp" *ngIf="selectedType === AuthFactorType.OTP">
|
||||||
<p class="desc cnsl-secondary-text">{{'USER.MFA.OTP_DIALOG_DESCRIPTION' | translate}}</p>
|
<p class="desc cnsl-secondary-text">{{ 'USER.MFA.OTP_DIALOG_DESCRIPTION' | translate }}</p>
|
||||||
|
|
||||||
<div class="qrcode-wrapper">
|
<div class="qrcode-wrapper">
|
||||||
<qr-code *ngIf="otpurl" class="qrcode" [value]="otpurl" [size]="150" [errorCorrectionLevel]="'M'"></qr-code>
|
<qr-code *ngIf="otpurl" class="qrcode" [value]="otpurl" [size]="150" [errorCorrectionLevel]="'M'"></qr-code>
|
||||||
|
|
||||||
|
<div class="otp-flex" *ngIf="otpsecret">
|
||||||
|
<span class="overflow-auto">{{ otpsecret }}</span>
|
||||||
|
<button
|
||||||
|
color="primary"
|
||||||
|
[disabled]="copied === otpsecret"
|
||||||
|
matTooltip="copy to clipboard"
|
||||||
|
cnslCopyToClipboard
|
||||||
|
[valueToCopy]="otpsecret"
|
||||||
|
(copiedValue)="this.copied = $event"
|
||||||
|
mat-icon-button
|
||||||
|
>
|
||||||
|
<i *ngIf="copied !== otpsecret" class="las la-clipboard"></i>
|
||||||
|
<i *ngIf="copied === otpsecret" class="las la-clipboard-check"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<cnsl-form-field class="formfield" label="Access Code" required="true">
|
<cnsl-form-field class="formfield" label="Access Code" required="true">
|
||||||
@ -39,25 +55,31 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="u2f" *ngIf="selectedType === AuthFactorType.U2F">
|
<div class="u2f" *ngIf="selectedType === AuthFactorType.U2F">
|
||||||
<p>{{'USER.MFA.U2F_DIALOG_DESCRIPTION' | translate}}</p>
|
<p>{{ 'USER.MFA.U2F_DIALOG_DESCRIPTION' | translate }}</p>
|
||||||
|
|
||||||
<cnsl-form-field class="form-field" label="Name" required="true">
|
<cnsl-form-field class="form-field" label="Name" required="true">
|
||||||
<cnsl-label>{{'USER.MFA.U2F_NAME' | translate}}</cnsl-label>
|
<cnsl-label>{{ 'USER.MFA.U2F_NAME' | translate }}</cnsl-label>
|
||||||
<input cnslInput [(ngModel)]="u2fname" required (keydown.enter)="u2fname ? submitU2F() : null" />
|
<input cnslInput [(ngModel)]="u2fname" required (keydown.enter)="u2fname ? submitU2F() : null" />
|
||||||
</cnsl-form-field>
|
</cnsl-form-field>
|
||||||
|
|
||||||
<mat-spinner diameter="30" *ngIf="u2fLoading"></mat-spinner>
|
<mat-spinner diameter="30" *ngIf="u2fLoading"></mat-spinner>
|
||||||
|
|
||||||
<p class="error">{{u2fError}}</p>
|
<p class="error">{{ u2fError }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div mat-dialog-actions class="action">
|
<div mat-dialog-actions class="action">
|
||||||
<button mat-stroked-button class="ok-button" (click)="closeDialog()">
|
<button mat-stroked-button class="ok-button" (click)="closeDialog()">
|
||||||
{{'ACTIONS.CLOSE' | translate}}
|
{{ 'ACTIONS.CLOSE' | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button *ngIf="selectedType !== undefined" cdkFocusInitial color="primary" mat-raised-button class="ok-button"
|
<button
|
||||||
(click)="submitAuth()">
|
*ngIf="selectedType !== undefined"
|
||||||
{{'ACTIONS.CREATE' | translate}}
|
cdkFocusInitial
|
||||||
|
color="primary"
|
||||||
|
mat-raised-button
|
||||||
|
class="ok-button"
|
||||||
|
(click)="submitAuth()"
|
||||||
|
>
|
||||||
|
{{ 'ACTIONS.CREATE' | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -33,6 +33,29 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
.qrcode-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.otp-flex {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border: 1px solid #ffffff20;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
padding-left: 0.5rem;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.overflow-auto {
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.desc {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.u2f {
|
.u2f {
|
||||||
|
@ -20,6 +20,8 @@ export enum AuthFactorType {
|
|||||||
})
|
})
|
||||||
export class AuthFactorDialogComponent {
|
export class AuthFactorDialogComponent {
|
||||||
public otpurl: string = '';
|
public otpurl: string = '';
|
||||||
|
public otpsecret: string = '';
|
||||||
|
|
||||||
public otpcode: string = '';
|
public otpcode: string = '';
|
||||||
|
|
||||||
public u2fname: string = '';
|
public u2fname: string = '';
|
||||||
@ -29,6 +31,8 @@ export class AuthFactorDialogComponent {
|
|||||||
|
|
||||||
AuthFactorType: any = AuthFactorType;
|
AuthFactorType: any = AuthFactorType;
|
||||||
selectedType!: AuthFactorType;
|
selectedType!: AuthFactorType;
|
||||||
|
|
||||||
|
public copied: string = '';
|
||||||
constructor(
|
constructor(
|
||||||
private authService: GrpcAuthService,
|
private authService: GrpcAuthService,
|
||||||
private toast: ToastService,
|
private toast: ToastService,
|
||||||
@ -48,6 +52,7 @@ export class AuthFactorDialogComponent {
|
|||||||
this.authService.addMyMultiFactorOTP().then(
|
this.authService.addMyMultiFactorOTP().then(
|
||||||
(otpresp) => {
|
(otpresp) => {
|
||||||
this.otpurl = otpresp.url;
|
this.otpurl = otpresp.url;
|
||||||
|
this.otpsecret = otpresp.secret;
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
this.toast.showError(error);
|
this.toast.showError(error);
|
||||||
|
@ -1,195 +1,203 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ActivateLabelPolicyRequest,
|
ActivateLabelPolicyRequest,
|
||||||
ActivateLabelPolicyResponse,
|
ActivateLabelPolicyResponse,
|
||||||
AddCustomDomainPolicyRequest,
|
ActivateSMSProviderRequest,
|
||||||
AddCustomOrgIAMPolicyResponse,
|
ActivateSMSProviderResponse,
|
||||||
AddIAMMemberRequest,
|
AddCustomDomainPolicyRequest,
|
||||||
AddIAMMemberResponse,
|
AddCustomOrgIAMPolicyResponse,
|
||||||
AddIDPToLoginPolicyRequest,
|
AddIAMMemberRequest,
|
||||||
AddIDPToLoginPolicyResponse,
|
AddIAMMemberResponse,
|
||||||
AddJWTIDPRequest,
|
AddIDPToLoginPolicyRequest,
|
||||||
AddJWTIDPResponse,
|
AddIDPToLoginPolicyResponse,
|
||||||
AddMultiFactorToLoginPolicyRequest,
|
AddJWTIDPRequest,
|
||||||
AddMultiFactorToLoginPolicyResponse,
|
AddJWTIDPResponse,
|
||||||
AddOIDCIDPRequest,
|
AddMultiFactorToLoginPolicyRequest,
|
||||||
AddOIDCIDPResponse,
|
AddMultiFactorToLoginPolicyResponse,
|
||||||
AddSecondFactorToLoginPolicyRequest,
|
AddOIDCIDPRequest,
|
||||||
AddSecondFactorToLoginPolicyResponse,
|
AddOIDCIDPResponse,
|
||||||
AddSMSProviderTwilioRequest,
|
AddSecondFactorToLoginPolicyRequest,
|
||||||
AddSMSProviderTwilioResponse,
|
AddSecondFactorToLoginPolicyResponse,
|
||||||
AddSMTPConfigRequest,
|
AddSMSProviderTwilioRequest,
|
||||||
AddSMTPConfigResponse,
|
AddSMSProviderTwilioResponse,
|
||||||
DeactivateIDPRequest,
|
AddSMTPConfigRequest,
|
||||||
DeactivateIDPResponse,
|
AddSMTPConfigResponse,
|
||||||
GetCustomDomainClaimedMessageTextRequest,
|
DeactivateIDPRequest,
|
||||||
GetCustomDomainClaimedMessageTextResponse,
|
DeactivateIDPResponse,
|
||||||
GetCustomDomainPolicyRequest,
|
DeactivateSMSProviderRequest,
|
||||||
GetCustomDomainPolicyResponse,
|
DeactivateSMSProviderResponse,
|
||||||
GetCustomInitMessageTextRequest,
|
GetCustomDomainClaimedMessageTextRequest,
|
||||||
GetCustomInitMessageTextResponse,
|
GetCustomDomainClaimedMessageTextResponse,
|
||||||
GetCustomLoginTextsRequest,
|
GetCustomDomainPolicyRequest,
|
||||||
GetCustomLoginTextsResponse,
|
GetCustomDomainPolicyResponse,
|
||||||
GetCustomPasswordlessRegistrationMessageTextRequest,
|
GetCustomInitMessageTextRequest,
|
||||||
GetCustomPasswordlessRegistrationMessageTextResponse,
|
GetCustomInitMessageTextResponse,
|
||||||
GetCustomPasswordResetMessageTextRequest,
|
GetCustomLoginTextsRequest,
|
||||||
GetCustomPasswordResetMessageTextResponse,
|
GetCustomLoginTextsResponse,
|
||||||
GetCustomVerifyEmailMessageTextRequest,
|
GetCustomPasswordlessRegistrationMessageTextRequest,
|
||||||
GetCustomVerifyEmailMessageTextResponse,
|
GetCustomPasswordlessRegistrationMessageTextResponse,
|
||||||
GetCustomVerifyPhoneMessageTextRequest,
|
GetCustomPasswordResetMessageTextRequest,
|
||||||
GetCustomVerifyPhoneMessageTextResponse,
|
GetCustomPasswordResetMessageTextResponse,
|
||||||
GetDefaultDomainClaimedMessageTextRequest,
|
GetCustomVerifyEmailMessageTextRequest,
|
||||||
GetDefaultDomainClaimedMessageTextResponse,
|
GetCustomVerifyEmailMessageTextResponse,
|
||||||
GetDefaultInitMessageTextRequest,
|
GetCustomVerifyPhoneMessageTextRequest,
|
||||||
GetDefaultInitMessageTextResponse,
|
GetCustomVerifyPhoneMessageTextResponse,
|
||||||
GetDefaultLanguageRequest,
|
GetDefaultDomainClaimedMessageTextRequest,
|
||||||
GetDefaultLanguageResponse,
|
GetDefaultDomainClaimedMessageTextResponse,
|
||||||
GetDefaultLoginTextsRequest,
|
GetDefaultInitMessageTextRequest,
|
||||||
GetDefaultLoginTextsResponse,
|
GetDefaultInitMessageTextResponse,
|
||||||
GetDefaultPasswordlessRegistrationMessageTextRequest,
|
GetDefaultLanguageRequest,
|
||||||
GetDefaultPasswordlessRegistrationMessageTextResponse,
|
GetDefaultLanguageResponse,
|
||||||
GetDefaultPasswordResetMessageTextRequest,
|
GetDefaultLoginTextsRequest,
|
||||||
GetDefaultPasswordResetMessageTextResponse,
|
GetDefaultLoginTextsResponse,
|
||||||
GetDefaultVerifyEmailMessageTextRequest,
|
GetDefaultPasswordlessRegistrationMessageTextRequest,
|
||||||
GetDefaultVerifyEmailMessageTextResponse,
|
GetDefaultPasswordlessRegistrationMessageTextResponse,
|
||||||
GetDefaultVerifyPhoneMessageTextRequest,
|
GetDefaultPasswordResetMessageTextRequest,
|
||||||
GetDefaultVerifyPhoneMessageTextResponse,
|
GetDefaultPasswordResetMessageTextResponse,
|
||||||
GetDomainPolicyRequest,
|
GetDefaultVerifyEmailMessageTextRequest,
|
||||||
GetDomainPolicyResponse,
|
GetDefaultVerifyEmailMessageTextResponse,
|
||||||
GetFileSystemNotificationProviderRequest,
|
GetDefaultVerifyPhoneMessageTextRequest,
|
||||||
GetFileSystemNotificationProviderResponse,
|
GetDefaultVerifyPhoneMessageTextResponse,
|
||||||
GetIDPByIDRequest,
|
GetDomainPolicyRequest,
|
||||||
GetIDPByIDResponse,
|
GetDomainPolicyResponse,
|
||||||
GetLabelPolicyRequest,
|
GetFileSystemNotificationProviderRequest,
|
||||||
GetLabelPolicyResponse,
|
GetFileSystemNotificationProviderResponse,
|
||||||
GetLockoutPolicyRequest,
|
GetIDPByIDRequest,
|
||||||
GetLockoutPolicyResponse,
|
GetIDPByIDResponse,
|
||||||
GetLoginPolicyRequest,
|
GetLabelPolicyRequest,
|
||||||
GetLoginPolicyResponse,
|
GetLabelPolicyResponse,
|
||||||
GetLogNotificationProviderRequest,
|
GetLockoutPolicyRequest,
|
||||||
GetLogNotificationProviderResponse,
|
GetLockoutPolicyResponse,
|
||||||
GetOIDCSettingsRequest,
|
GetLoginPolicyRequest,
|
||||||
GetOIDCSettingsResponse,
|
GetLoginPolicyResponse,
|
||||||
GetPasswordAgePolicyRequest,
|
GetLogNotificationProviderRequest,
|
||||||
GetPasswordAgePolicyResponse,
|
GetLogNotificationProviderResponse,
|
||||||
GetPasswordComplexityPolicyRequest,
|
GetMyInstanceRequest,
|
||||||
GetPasswordComplexityPolicyResponse,
|
GetMyInstanceResponse,
|
||||||
GetPreviewLabelPolicyRequest,
|
GetOIDCSettingsRequest,
|
||||||
GetPreviewLabelPolicyResponse,
|
GetOIDCSettingsResponse,
|
||||||
GetPrivacyPolicyRequest,
|
GetPasswordAgePolicyRequest,
|
||||||
GetPrivacyPolicyResponse,
|
GetPasswordAgePolicyResponse,
|
||||||
GetSecretGeneratorRequest,
|
GetPasswordComplexityPolicyRequest,
|
||||||
GetSecretGeneratorResponse,
|
GetPasswordComplexityPolicyResponse,
|
||||||
GetSMSProviderRequest,
|
GetPreviewLabelPolicyRequest,
|
||||||
GetSMSProviderResponse,
|
GetPreviewLabelPolicyResponse,
|
||||||
GetSMTPConfigRequest,
|
GetPrivacyPolicyRequest,
|
||||||
GetSMTPConfigResponse,
|
GetPrivacyPolicyResponse,
|
||||||
GetSupportedLanguagesRequest,
|
GetSecretGeneratorRequest,
|
||||||
GetSupportedLanguagesResponse,
|
GetSecretGeneratorResponse,
|
||||||
IDPQuery,
|
GetSMSProviderRequest,
|
||||||
ListFailedEventsRequest,
|
GetSMSProviderResponse,
|
||||||
ListFailedEventsResponse,
|
GetSMTPConfigRequest,
|
||||||
ListIAMMemberRolesRequest,
|
GetSMTPConfigResponse,
|
||||||
ListIAMMemberRolesResponse,
|
GetSupportedLanguagesRequest,
|
||||||
ListIAMMembersRequest,
|
GetSupportedLanguagesResponse,
|
||||||
ListIAMMembersResponse,
|
IDPQuery,
|
||||||
ListIDPsRequest,
|
ListFailedEventsRequest,
|
||||||
ListIDPsResponse,
|
ListFailedEventsResponse,
|
||||||
ListLoginPolicyIDPsRequest,
|
ListIAMMemberRolesRequest,
|
||||||
ListLoginPolicyIDPsResponse,
|
ListIAMMemberRolesResponse,
|
||||||
ListLoginPolicyMultiFactorsRequest,
|
ListIAMMembersRequest,
|
||||||
ListLoginPolicyMultiFactorsResponse,
|
ListIAMMembersResponse,
|
||||||
ListLoginPolicySecondFactorsRequest,
|
ListIDPsRequest,
|
||||||
ListLoginPolicySecondFactorsResponse,
|
ListIDPsResponse,
|
||||||
ListSecretGeneratorsRequest,
|
ListLoginPolicyIDPsRequest,
|
||||||
ListSecretGeneratorsResponse,
|
ListLoginPolicyIDPsResponse,
|
||||||
ListSMSProvidersRequest,
|
ListLoginPolicyMultiFactorsRequest,
|
||||||
ListSMSProvidersResponse,
|
ListLoginPolicyMultiFactorsResponse,
|
||||||
ListViewsRequest,
|
ListLoginPolicySecondFactorsRequest,
|
||||||
ListViewsResponse,
|
ListLoginPolicySecondFactorsResponse,
|
||||||
ReactivateIDPRequest,
|
ListSecretGeneratorsRequest,
|
||||||
ReactivateIDPResponse,
|
ListSecretGeneratorsResponse,
|
||||||
RemoveFailedEventRequest,
|
ListSMSProvidersRequest,
|
||||||
RemoveFailedEventResponse,
|
ListSMSProvidersResponse,
|
||||||
RemoveIAMMemberRequest,
|
ListViewsRequest,
|
||||||
RemoveIAMMemberResponse,
|
ListViewsResponse,
|
||||||
RemoveIDPFromLoginPolicyRequest,
|
ReactivateIDPRequest,
|
||||||
RemoveIDPFromLoginPolicyResponse,
|
ReactivateIDPResponse,
|
||||||
RemoveIDPRequest,
|
RemoveFailedEventRequest,
|
||||||
RemoveIDPResponse,
|
RemoveFailedEventResponse,
|
||||||
RemoveLabelPolicyFontRequest,
|
RemoveIAMMemberRequest,
|
||||||
RemoveLabelPolicyFontResponse,
|
RemoveIAMMemberResponse,
|
||||||
RemoveLabelPolicyIconDarkRequest,
|
RemoveIDPFromLoginPolicyRequest,
|
||||||
RemoveLabelPolicyIconDarkResponse,
|
RemoveIDPFromLoginPolicyResponse,
|
||||||
RemoveLabelPolicyIconRequest,
|
RemoveIDPRequest,
|
||||||
RemoveLabelPolicyIconResponse,
|
RemoveIDPResponse,
|
||||||
RemoveLabelPolicyLogoDarkRequest,
|
RemoveLabelPolicyFontRequest,
|
||||||
RemoveLabelPolicyLogoDarkResponse,
|
RemoveLabelPolicyFontResponse,
|
||||||
RemoveLabelPolicyLogoRequest,
|
RemoveLabelPolicyIconDarkRequest,
|
||||||
RemoveLabelPolicyLogoResponse,
|
RemoveLabelPolicyIconDarkResponse,
|
||||||
RemoveMultiFactorFromLoginPolicyRequest,
|
RemoveLabelPolicyIconRequest,
|
||||||
RemoveMultiFactorFromLoginPolicyResponse,
|
RemoveLabelPolicyIconResponse,
|
||||||
RemoveSecondFactorFromLoginPolicyRequest,
|
RemoveLabelPolicyLogoDarkRequest,
|
||||||
RemoveSecondFactorFromLoginPolicyResponse,
|
RemoveLabelPolicyLogoDarkResponse,
|
||||||
ResetCustomDomainPolicyToDefaultRequest,
|
RemoveLabelPolicyLogoRequest,
|
||||||
ResetCustomDomainPolicyToDefaultResponse,
|
RemoveLabelPolicyLogoResponse,
|
||||||
ResetCustomLoginTextsToDefaultRequest,
|
RemoveMultiFactorFromLoginPolicyRequest,
|
||||||
ResetCustomLoginTextsToDefaultResponse,
|
RemoveMultiFactorFromLoginPolicyResponse,
|
||||||
SetCustomLoginTextsRequest,
|
RemoveSecondFactorFromLoginPolicyRequest,
|
||||||
SetCustomLoginTextsResponse,
|
RemoveSecondFactorFromLoginPolicyResponse,
|
||||||
SetDefaultDomainClaimedMessageTextRequest,
|
RemoveSMSProviderRequest,
|
||||||
SetDefaultDomainClaimedMessageTextResponse,
|
RemoveSMSProviderResponse,
|
||||||
SetDefaultInitMessageTextRequest,
|
ResetCustomDomainPolicyToDefaultRequest,
|
||||||
SetDefaultInitMessageTextResponse,
|
ResetCustomDomainPolicyToDefaultResponse,
|
||||||
SetDefaultLanguageRequest,
|
ResetCustomLoginTextsToDefaultRequest,
|
||||||
SetDefaultLanguageResponse,
|
ResetCustomLoginTextsToDefaultResponse,
|
||||||
SetDefaultPasswordlessRegistrationMessageTextRequest,
|
SetCustomLoginTextsRequest,
|
||||||
SetDefaultPasswordlessRegistrationMessageTextResponse,
|
SetCustomLoginTextsResponse,
|
||||||
SetDefaultPasswordResetMessageTextRequest,
|
SetDefaultDomainClaimedMessageTextRequest,
|
||||||
SetDefaultPasswordResetMessageTextResponse,
|
SetDefaultDomainClaimedMessageTextResponse,
|
||||||
SetDefaultVerifyEmailMessageTextRequest,
|
SetDefaultInitMessageTextRequest,
|
||||||
SetDefaultVerifyEmailMessageTextResponse,
|
SetDefaultInitMessageTextResponse,
|
||||||
SetDefaultVerifyPhoneMessageTextRequest,
|
SetDefaultLanguageRequest,
|
||||||
SetDefaultVerifyPhoneMessageTextResponse,
|
SetDefaultLanguageResponse,
|
||||||
SetUpOrgRequest,
|
SetDefaultPasswordlessRegistrationMessageTextRequest,
|
||||||
SetUpOrgResponse,
|
SetDefaultPasswordlessRegistrationMessageTextResponse,
|
||||||
UpdateCustomDomainPolicyRequest,
|
SetDefaultPasswordResetMessageTextRequest,
|
||||||
UpdateCustomDomainPolicyResponse,
|
SetDefaultPasswordResetMessageTextResponse,
|
||||||
UpdateDomainPolicyRequest,
|
SetDefaultVerifyEmailMessageTextRequest,
|
||||||
UpdateDomainPolicyResponse,
|
SetDefaultVerifyEmailMessageTextResponse,
|
||||||
UpdateIAMMemberRequest,
|
SetDefaultVerifyPhoneMessageTextRequest,
|
||||||
UpdateIAMMemberResponse,
|
SetDefaultVerifyPhoneMessageTextResponse,
|
||||||
UpdateIDPJWTConfigRequest,
|
SetUpOrgRequest,
|
||||||
UpdateIDPJWTConfigResponse,
|
SetUpOrgResponse,
|
||||||
UpdateIDPOIDCConfigRequest,
|
UpdateCustomDomainPolicyRequest,
|
||||||
UpdateIDPOIDCConfigResponse,
|
UpdateCustomDomainPolicyResponse,
|
||||||
UpdateIDPRequest,
|
UpdateDomainPolicyRequest,
|
||||||
UpdateIDPResponse,
|
UpdateDomainPolicyResponse,
|
||||||
UpdateLabelPolicyRequest,
|
UpdateIAMMemberRequest,
|
||||||
UpdateLabelPolicyResponse,
|
UpdateIAMMemberResponse,
|
||||||
UpdateLockoutPolicyRequest,
|
UpdateIDPJWTConfigRequest,
|
||||||
UpdateLockoutPolicyResponse,
|
UpdateIDPJWTConfigResponse,
|
||||||
UpdateLoginPolicyRequest,
|
UpdateIDPOIDCConfigRequest,
|
||||||
UpdateLoginPolicyResponse,
|
UpdateIDPOIDCConfigResponse,
|
||||||
UpdateOIDCSettingsRequest,
|
UpdateIDPRequest,
|
||||||
UpdateOIDCSettingsResponse,
|
UpdateIDPResponse,
|
||||||
UpdatePasswordAgePolicyRequest,
|
UpdateLabelPolicyRequest,
|
||||||
UpdatePasswordAgePolicyResponse,
|
UpdateLabelPolicyResponse,
|
||||||
UpdatePasswordComplexityPolicyRequest,
|
UpdateLockoutPolicyRequest,
|
||||||
UpdatePasswordComplexityPolicyResponse,
|
UpdateLockoutPolicyResponse,
|
||||||
UpdatePrivacyPolicyRequest,
|
UpdateLoginPolicyRequest,
|
||||||
UpdatePrivacyPolicyResponse,
|
UpdateLoginPolicyResponse,
|
||||||
UpdateSecretGeneratorRequest,
|
UpdateOIDCSettingsRequest,
|
||||||
UpdateSecretGeneratorResponse,
|
UpdateOIDCSettingsResponse,
|
||||||
UpdateSMSProviderTwilioRequest,
|
UpdatePasswordAgePolicyRequest,
|
||||||
UpdateSMSProviderTwilioResponse,
|
UpdatePasswordAgePolicyResponse,
|
||||||
UpdateSMSProviderTwilioTokenRequest,
|
UpdatePasswordComplexityPolicyRequest,
|
||||||
UpdateSMSProviderTwilioTokenResponse,
|
UpdatePasswordComplexityPolicyResponse,
|
||||||
UpdateSMTPConfigPasswordRequest,
|
UpdatePrivacyPolicyRequest,
|
||||||
UpdateSMTPConfigPasswordResponse,
|
UpdatePrivacyPolicyResponse,
|
||||||
UpdateSMTPConfigRequest,
|
UpdateSecretGeneratorRequest,
|
||||||
UpdateSMTPConfigResponse,
|
UpdateSecretGeneratorResponse,
|
||||||
|
UpdateSMSProviderTwilioRequest,
|
||||||
|
UpdateSMSProviderTwilioResponse,
|
||||||
|
UpdateSMSProviderTwilioTokenRequest,
|
||||||
|
UpdateSMSProviderTwilioTokenResponse,
|
||||||
|
UpdateSMTPConfigPasswordRequest,
|
||||||
|
UpdateSMTPConfigPasswordResponse,
|
||||||
|
UpdateSMTPConfigRequest,
|
||||||
|
UpdateSMTPConfigResponse,
|
||||||
} from '../proto/generated/zitadel/admin_pb';
|
} from '../proto/generated/zitadel/admin_pb';
|
||||||
import { SearchQuery } from '../proto/generated/zitadel/member_pb';
|
import { SearchQuery } from '../proto/generated/zitadel/member_pb';
|
||||||
import { ListQuery } from '../proto/generated/zitadel/object_pb';
|
import { ListQuery } from '../proto/generated/zitadel/object_pb';
|
||||||
@ -398,6 +406,11 @@ export class AdminService {
|
|||||||
return this.grpcService.admin.removeFailedEvent(req, null).then((resp) => resp.toObject());
|
return this.grpcService.admin.removeFailedEvent(req, null).then((resp) => resp.toObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getMyInstance(): Promise<GetMyInstanceResponse.AsObject> {
|
||||||
|
const req = new GetMyInstanceRequest();
|
||||||
|
return this.grpcService.admin.getMyInstance(req, null).then((resp) => resp.toObject());
|
||||||
|
}
|
||||||
|
|
||||||
public getPrivacyPolicy(): Promise<GetPrivacyPolicyResponse.AsObject> {
|
public getPrivacyPolicy(): Promise<GetPrivacyPolicyResponse.AsObject> {
|
||||||
const req = new GetPrivacyPolicyRequest();
|
const req = new GetPrivacyPolicyRequest();
|
||||||
return this.grpcService.admin.getPrivacyPolicy(req, null).then((resp) => resp.toObject());
|
return this.grpcService.admin.getPrivacyPolicy(req, null).then((resp) => resp.toObject());
|
||||||
@ -504,6 +517,24 @@ export class AdminService {
|
|||||||
return this.grpcService.admin.updateSMSProviderTwilio(req, null).then((resp) => resp.toObject());
|
return this.grpcService.admin.updateSMSProviderTwilio(req, null).then((resp) => resp.toObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public removeSMSProvider(id: string): Promise<RemoveSMSProviderResponse.AsObject> {
|
||||||
|
const req = new RemoveSMSProviderRequest();
|
||||||
|
req.setId(id);
|
||||||
|
return this.grpcService.admin.removeSMSProvider(req, null).then((resp) => resp.toObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
public activateSMSProvider(id: string): Promise<ActivateSMSProviderResponse.AsObject> {
|
||||||
|
const req = new ActivateSMSProviderRequest();
|
||||||
|
req.setId(id);
|
||||||
|
return this.grpcService.admin.activateSMSProvider(req, null).then((resp) => resp.toObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
public deactivateSMSProvider(id: string): Promise<DeactivateSMSProviderResponse.AsObject> {
|
||||||
|
const req = new DeactivateSMSProviderRequest();
|
||||||
|
req.setId(id);
|
||||||
|
return this.grpcService.admin.deactivateSMSProvider(req, null).then((resp) => resp.toObject());
|
||||||
|
}
|
||||||
|
|
||||||
public updateSMSProviderTwilioToken(
|
public updateSMSProviderTwilioToken(
|
||||||
req: UpdateSMSProviderTwilioTokenRequest,
|
req: UpdateSMSProviderTwilioTokenRequest,
|
||||||
): Promise<UpdateSMSProviderTwilioTokenResponse.AsObject> {
|
): Promise<UpdateSMSProviderTwilioTokenResponse.AsObject> {
|
||||||
|
@ -106,6 +106,7 @@
|
|||||||
"FINISHED": "Fertig",
|
"FINISHED": "Fertig",
|
||||||
"CHANGE": "Ändern",
|
"CHANGE": "Ändern",
|
||||||
"REACTIVATE": "Aktivieren",
|
"REACTIVATE": "Aktivieren",
|
||||||
|
"ACTIVATE": "Aktivieren",
|
||||||
"DEACTIVATE": "Deaktivieren",
|
"DEACTIVATE": "Deaktivieren",
|
||||||
"REFRESH": "Aktualisieren",
|
"REFRESH": "Aktualisieren",
|
||||||
"LOGIN": "Einloggen",
|
"LOGIN": "Einloggen",
|
||||||
@ -193,6 +194,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"RESOURCEID": "Ressourcen-ID",
|
"RESOURCEID": "Ressourcen-ID",
|
||||||
|
"NAME": "Name",
|
||||||
|
"VERSION": "Version",
|
||||||
"TABLE": {
|
"TABLE": {
|
||||||
"NOROWS": "Keine Daten"
|
"NOROWS": "Keine Daten"
|
||||||
},
|
},
|
||||||
@ -706,6 +709,17 @@
|
|||||||
"TITLE": "Manager",
|
"TITLE": "Manager",
|
||||||
"DESCRIPTION": "Diese Manager können instanzweite Einstellungen vornehmen."
|
"DESCRIPTION": "Diese Manager können instanzweite Einstellungen vornehmen."
|
||||||
},
|
},
|
||||||
|
"PAGES": {
|
||||||
|
"STATE": "Status",
|
||||||
|
"DOMAINLIST": "Domains"
|
||||||
|
},
|
||||||
|
"STATE": {
|
||||||
|
"0": "Unspezifisch",
|
||||||
|
"1": "Wird erstellt",
|
||||||
|
"2": "Aktiv",
|
||||||
|
"3": "Wird gestoppt",
|
||||||
|
"4": "Gestoppt"
|
||||||
|
},
|
||||||
"VIEWS": {
|
"VIEWS": {
|
||||||
"TITLE": "Views",
|
"TITLE": "Views",
|
||||||
"DESCRIPTION": "Diese Ansicht zeigt die Anzeigen von ZITADEL. Diese können bei Bedarf zurückgesetzt werden.",
|
"DESCRIPTION": "Diese Ansicht zeigt die Anzeigen von ZITADEL. Diese können bei Bedarf zurückgesetzt werden.",
|
||||||
@ -896,11 +910,21 @@
|
|||||||
"PROVIDER": "SMS Anbieter",
|
"PROVIDER": "SMS Anbieter",
|
||||||
"ADDPROVIDER": "Anbieter hinzufügen",
|
"ADDPROVIDER": "Anbieter hinzufügen",
|
||||||
"ADDPROVIDERDESCRIPTION": "Wählen Sie einen der verfügbaren Anbieter und geben Sie die erforderlichen Daten ein.",
|
"ADDPROVIDERDESCRIPTION": "Wählen Sie einen der verfügbaren Anbieter und geben Sie die erforderlichen Daten ein.",
|
||||||
|
"REMOVEPROVIDER": "Anbieter entfernen",
|
||||||
|
"REMOVEPROVIDER_DESC": "Sie sind im Begriff eine Konfiguration zu löschen. Wollen Sie fortfahren?",
|
||||||
|
"SMSPROVIDERSTATE": {
|
||||||
|
"0": "Unbekannt",
|
||||||
|
"1": "Aktiv",
|
||||||
|
"2": "Inaktiv"
|
||||||
|
},
|
||||||
|
"ACTIVATED": "Anbieter aktiviert.",
|
||||||
|
"DEACTIVATED": "Anbieter deaktiviert.",
|
||||||
"TWILIO": {
|
"TWILIO": {
|
||||||
"SID": "Sid",
|
"SID": "Sid",
|
||||||
"TOKEN": "Token",
|
"TOKEN": "Token",
|
||||||
"SENDERNUMBER": "Sender Number",
|
"SENDERNUMBER": "Sender Number",
|
||||||
"ADDED": "Twilio erfolgreich hinzugefügt.",
|
"ADDED": "Twilio erfolgreich hinzugefügt.",
|
||||||
|
"REMOVED": "Twilio entfernt",
|
||||||
"CHANGETOKEN": "Token ändern",
|
"CHANGETOKEN": "Token ändern",
|
||||||
"SETTOKEN": "Token setzen",
|
"SETTOKEN": "Token setzen",
|
||||||
"TOKENSET": "Token erfolgreich gesetzt."
|
"TOKENSET": "Token erfolgreich gesetzt."
|
||||||
|
@ -106,6 +106,7 @@
|
|||||||
"FINISHED": "Close",
|
"FINISHED": "Close",
|
||||||
"CHANGE": "Change",
|
"CHANGE": "Change",
|
||||||
"REACTIVATE": "Reactivate",
|
"REACTIVATE": "Reactivate",
|
||||||
|
"ACTIVATE": "Activate",
|
||||||
"DEACTIVATE": "Deactivate",
|
"DEACTIVATE": "Deactivate",
|
||||||
"REFRESH": "Refresh",
|
"REFRESH": "Refresh",
|
||||||
"LOGIN": "Login",
|
"LOGIN": "Login",
|
||||||
@ -193,6 +194,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"RESOURCEID": "Resource Id",
|
"RESOURCEID": "Resource Id",
|
||||||
|
"NAME": "Name",
|
||||||
|
"VERSION": "Version",
|
||||||
"TABLE": {
|
"TABLE": {
|
||||||
"NOROWS": "No data"
|
"NOROWS": "No data"
|
||||||
},
|
},
|
||||||
@ -706,6 +709,17 @@
|
|||||||
"TITLE": "Managers",
|
"TITLE": "Managers",
|
||||||
"DESCRIPTION": "These Managers are allowed to make changes in your instance."
|
"DESCRIPTION": "These Managers are allowed to make changes in your instance."
|
||||||
},
|
},
|
||||||
|
"PAGES": {
|
||||||
|
"STATE": "Status",
|
||||||
|
"DOMAINLIST": "Domains"
|
||||||
|
},
|
||||||
|
"STATE": {
|
||||||
|
"0": "Unspecified",
|
||||||
|
"1": "Creating",
|
||||||
|
"2": "Running",
|
||||||
|
"3": "Stopping",
|
||||||
|
"4": "Stopped"
|
||||||
|
},
|
||||||
"VIEWS": {
|
"VIEWS": {
|
||||||
"TITLE": "Views",
|
"TITLE": "Views",
|
||||||
"DESCRIPTION": "This card shows your ZITADEL views.",
|
"DESCRIPTION": "This card shows your ZITADEL views.",
|
||||||
@ -874,7 +888,8 @@
|
|||||||
"LANGUAGE": {
|
"LANGUAGE": {
|
||||||
"de": "Deutsch",
|
"de": "Deutsch",
|
||||||
"it": "Italiano",
|
"it": "Italiano",
|
||||||
"en": "English"
|
"en": "English",
|
||||||
|
"fr": "Français"
|
||||||
},
|
},
|
||||||
"SMTP": {
|
"SMTP": {
|
||||||
"TITLE": "SMTP Settings",
|
"TITLE": "SMTP Settings",
|
||||||
@ -895,11 +910,21 @@
|
|||||||
"PROVIDER": "SMS Provider",
|
"PROVIDER": "SMS Provider",
|
||||||
"ADDPROVIDER": "Add SMS Provider",
|
"ADDPROVIDER": "Add SMS Provider",
|
||||||
"ADDPROVIDERDESCRIPTION": "Choose one of the available providers and enter the required data.",
|
"ADDPROVIDERDESCRIPTION": "Choose one of the available providers and enter the required data.",
|
||||||
|
"REMOVEPROVIDER": "Remove Provider",
|
||||||
|
"REMOVEPROVIDER_DESC": "You are about to delete a provider configuration. Do you want to continue?",
|
||||||
|
"SMSPROVIDERSTATE": {
|
||||||
|
"0": "Unspecified",
|
||||||
|
"1": "Active",
|
||||||
|
"2": "Inactive"
|
||||||
|
},
|
||||||
|
"ACTIVATED": "Provider activated.",
|
||||||
|
"DEACTIVATED": "Provider deactivated.",
|
||||||
"TWILIO": {
|
"TWILIO": {
|
||||||
"SID": "Sid",
|
"SID": "Sid",
|
||||||
"TOKEN": "Token",
|
"TOKEN": "Token",
|
||||||
"SENDERNUMBER": "Sender Number",
|
"SENDERNUMBER": "Sender Number",
|
||||||
"ADDED": "Twilio added successfully.",
|
"ADDED": "Twilio added successfully.",
|
||||||
|
"REMOVED": "Twilio removed",
|
||||||
"CHANGETOKEN": "Change Token",
|
"CHANGETOKEN": "Change Token",
|
||||||
"SETTOKEN": "Set Token",
|
"SETTOKEN": "Set Token",
|
||||||
"TOKENSET": "Token successfully set."
|
"TOKENSET": "Token successfully set."
|
||||||
|
@ -106,6 +106,7 @@
|
|||||||
"FINISHED": "Fermer",
|
"FINISHED": "Fermer",
|
||||||
"CHANGE": "Modifier",
|
"CHANGE": "Modifier",
|
||||||
"REACTIVATE": "Réactiver",
|
"REACTIVATE": "Réactiver",
|
||||||
|
"ACTIVATE": "Activer",
|
||||||
"DEACTIVATE": "Désactiver",
|
"DEACTIVATE": "Désactiver",
|
||||||
"REFRESH": "Rafraîchir",
|
"REFRESH": "Rafraîchir",
|
||||||
"LOGIN": "Connexion",
|
"LOGIN": "Connexion",
|
||||||
@ -193,6 +194,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"RESOURCEID": "Id de la ressource",
|
"RESOURCEID": "Id de la ressource",
|
||||||
|
"NAME": "Name",
|
||||||
|
"VERSION": "Version",
|
||||||
"TABLE": {
|
"TABLE": {
|
||||||
"NOROWS": "Pas de données"
|
"NOROWS": "Pas de données"
|
||||||
},
|
},
|
||||||
@ -706,6 +709,17 @@
|
|||||||
"TITLE": "Managers",
|
"TITLE": "Managers",
|
||||||
"DESCRIPTION": "Ces gestionnaires sont autorisés à effectuer des changements dans votre instance."
|
"DESCRIPTION": "Ces gestionnaires sont autorisés à effectuer des changements dans votre instance."
|
||||||
},
|
},
|
||||||
|
"PAGES": {
|
||||||
|
"STATE": "Statut",
|
||||||
|
"DOMAINLIST": "Domaines"
|
||||||
|
},
|
||||||
|
"STATE": {
|
||||||
|
"0": "Inconnu",
|
||||||
|
"1": "Créer",
|
||||||
|
"2": "Actif",
|
||||||
|
"3": "Arrêt",
|
||||||
|
"4": "Arrêté"
|
||||||
|
},
|
||||||
"VIEWS": {
|
"VIEWS": {
|
||||||
"TITLE": "Vues",
|
"TITLE": "Vues",
|
||||||
"DESCRIPTION": "Cette carte montre vos vues ZITADEL.",
|
"DESCRIPTION": "Cette carte montre vos vues ZITADEL.",
|
||||||
@ -896,11 +910,21 @@
|
|||||||
"PROVIDER": "Fournisseur de SMS",
|
"PROVIDER": "Fournisseur de SMS",
|
||||||
"ADDPROVIDER": "Ajouter un fournisseur de SMS",
|
"ADDPROVIDER": "Ajouter un fournisseur de SMS",
|
||||||
"ADDPROVIDERDESCRIPTION": "Choisissez l'un des fournisseurs disponibles et saisissez les données requises.",
|
"ADDPROVIDERDESCRIPTION": "Choisissez l'un des fournisseurs disponibles et saisissez les données requises.",
|
||||||
|
"REMOVEPROVIDER": "Supprimer le fournisseur",
|
||||||
|
"REMOVEPROVIDER_DESC": "Vous êtes sur le point de supprimer une configuration de fournisseur. Voulez-vous continuer",
|
||||||
|
"SMSPROVIDERSTATE": {
|
||||||
|
"0": "non spécifié",
|
||||||
|
"1": "Actif",
|
||||||
|
"2": "Inactif"
|
||||||
|
},
|
||||||
|
"ACTIVATED": "Fournisseur actif.",
|
||||||
|
"DEACTIVATED": "Fournisseur inactif.",
|
||||||
"TWILIO": {
|
"TWILIO": {
|
||||||
"SID": "Sid",
|
"SID": "Sid",
|
||||||
"TOKEN": "Jeton",
|
"TOKEN": "Jeton",
|
||||||
"SENDERNUMBER": "Numéro d'expéditeur",
|
"SENDERNUMBER": "Numéro d'expéditeur",
|
||||||
"ADDED": "Twilio a été ajouté avec succès.",
|
"ADDED": "Twilio a été ajouté avec succès.",
|
||||||
|
"REMOVED": "Twilio a été supprimé avec succès",
|
||||||
"CHANGETOKEN": "Changer de Token",
|
"CHANGETOKEN": "Changer de Token",
|
||||||
"SETTOKEN": "Définir le jeton",
|
"SETTOKEN": "Définir le jeton",
|
||||||
"TOKENSET": "Le jeton a été défini avec succès."
|
"TOKENSET": "Le jeton a été défini avec succès."
|
||||||
|
@ -106,6 +106,7 @@
|
|||||||
"FINISHED": "Chiudi",
|
"FINISHED": "Chiudi",
|
||||||
"CHANGE": "Cambia",
|
"CHANGE": "Cambia",
|
||||||
"REACTIVATE": "Riattiva",
|
"REACTIVATE": "Riattiva",
|
||||||
|
"ACTIVATE": "Attiva",
|
||||||
"DEACTIVATE": "Disattiva",
|
"DEACTIVATE": "Disattiva",
|
||||||
"REFRESH": "Aggiorna",
|
"REFRESH": "Aggiorna",
|
||||||
"LOGIN": "Accedi",
|
"LOGIN": "Accedi",
|
||||||
@ -193,6 +194,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"RESOURCEID": "Resource ID",
|
"RESOURCEID": "Resource ID",
|
||||||
|
"NAME": "Name",
|
||||||
|
"VERSION": "Versione",
|
||||||
"TABLE": {
|
"TABLE": {
|
||||||
"NOROWS": "Nessun dato"
|
"NOROWS": "Nessun dato"
|
||||||
},
|
},
|
||||||
@ -706,6 +709,17 @@
|
|||||||
"TITLE": "Manager",
|
"TITLE": "Manager",
|
||||||
"DESCRIPTION": "Questi manager possono modificare le impostazioni dell'istanza."
|
"DESCRIPTION": "Questi manager possono modificare le impostazioni dell'istanza."
|
||||||
},
|
},
|
||||||
|
"PAGES": {
|
||||||
|
"STATE": "Stato",
|
||||||
|
"DOMAINLIST": "Domini"
|
||||||
|
},
|
||||||
|
"STATE": {
|
||||||
|
"0": "Non specifico",
|
||||||
|
"1": "In fase di creazione",
|
||||||
|
"2": "Attiva",
|
||||||
|
"3": "In fase di arresto",
|
||||||
|
"4": "Arrestata"
|
||||||
|
},
|
||||||
"VIEWS": {
|
"VIEWS": {
|
||||||
"TITLE": "Views",
|
"TITLE": "Views",
|
||||||
"DESCRIPTION": "Questa carta mostra i tuoi view ZITADEL.",
|
"DESCRIPTION": "Questa carta mostra i tuoi view ZITADEL.",
|
||||||
@ -896,11 +910,21 @@
|
|||||||
"PROVIDER": "Fornitore SMS",
|
"PROVIDER": "Fornitore SMS",
|
||||||
"ADDPROVIDER": "Aggiungi fornitore SMS",
|
"ADDPROVIDER": "Aggiungi fornitore SMS",
|
||||||
"ADDPROVIDERDESCRIPTION": "Scegli uno dei provider disponibili e inserisci i dati richiesti.",
|
"ADDPROVIDERDESCRIPTION": "Scegli uno dei provider disponibili e inserisci i dati richiesti.",
|
||||||
|
"REMOVEPROVIDER": "Elimina configurazione",
|
||||||
|
"REMOVEPROVIDER_DESC": "Stai per eliminare una configurazione. Vuoi continuare?",
|
||||||
|
"SMSPROVIDERSTATE": {
|
||||||
|
"0": "Non specificato",
|
||||||
|
"1": "Attivo",
|
||||||
|
"2": "Inattivo"
|
||||||
|
},
|
||||||
|
"ACTIVATED": "Fornitore attivato.",
|
||||||
|
"DEACTIVATED": "Fornitore disattivato.",
|
||||||
"TWILIO": {
|
"TWILIO": {
|
||||||
"SID": "Sid",
|
"SID": "Sid",
|
||||||
"TOKEN": "Token",
|
"TOKEN": "Token",
|
||||||
"SENDERNUMBER": "Sender Number",
|
"SENDERNUMBER": "Sender Number",
|
||||||
"ADDED": "Twilio aggiunto con successo.",
|
"ADDED": "Twilio aggiunto con successo.",
|
||||||
|
"REMOVED": "Twilio rimosso con successo.",
|
||||||
"CHANGETOKEN": "Cambia Token",
|
"CHANGETOKEN": "Cambia Token",
|
||||||
"SETTOKEN": "Cambia Token",
|
"SETTOKEN": "Cambia Token",
|
||||||
"TOKENSET": "Token cambiato con successo."
|
"TOKENSET": "Token cambiato con successo."
|
||||||
|
@ -10,30 +10,32 @@ Please check below the matrix for an overview where which scope is asserted.
|
|||||||
| acr | No | No | Yes | No |
|
| acr | No | No | Yes | No |
|
||||||
| address | When requested | When requested | When requested amd response_type `id_token` | No |
|
| address | When requested | When requested | When requested amd response_type `id_token` | No |
|
||||||
| amr | No | No | Yes | No |
|
| amr | No | No | Yes | No |
|
||||||
| aud | No | No | Yes | When JWT |
|
| aud | No | Yes | Yes | When JWT |
|
||||||
| auth_time | No | No | Yes | No |
|
| auth_time | No | No | Yes | No |
|
||||||
| azp | No | No | Yes | When JWT |
|
| azp (client_id when Introspect) | No | Yes | Yes | When JWT |
|
||||||
| email | When requested | When requested | When requested amd response_type `id_token` | No |
|
| email | When requested | When requested | When requested amd response_type `id_token` | No |
|
||||||
| email_verified | When requested | When requested | When requested amd response_type `id_token` | No |
|
| email_verified | When requested | When requested | When requested amd response_type `id_token` | No |
|
||||||
| exp | No | No | Yes | When JWT |
|
| exp | No | Yes | Yes | When JWT |
|
||||||
| family_name | When requested | When requested | When requested amd response_type `id_token` | No |
|
| family_name | When requested | When requested | When requested amd response_type `id_token` | No |
|
||||||
| gender | When requested | When requested | When requested amd response_type `id_token` | No |
|
| gender | When requested | When requested | When requested amd response_type `id_token` | No |
|
||||||
| given_name | When requested | When requested | When requested amd response_type `id_token` | No |
|
| given_name | When requested | When requested | When requested amd response_type `id_token` | No |
|
||||||
| iat | No | No | Yes | When JWT |
|
| iat | No | Yes | Yes | When JWT |
|
||||||
| iss | No | No | Yes | When JWT |
|
| iss | No | Yes | Yes | When JWT |
|
||||||
|
| jti | No | Yes | No | When JWT |
|
||||||
| locale | When requested | When requested | When requested amd response_type `id_token` | No |
|
| locale | When requested | When requested | When requested amd response_type `id_token` | No |
|
||||||
| name | When requested | When requested | When requested amd response_type `id_token` | No |
|
| name | When requested | When requested | When requested amd response_type `id_token` | No |
|
||||||
|
| nbf | No | Yes | Yes | When JWT |
|
||||||
| nonce | No | No | Yes | No |
|
| nonce | No | No | Yes | No |
|
||||||
| phone | When requested | When requested | When requested amd response_type `id_token` | No |
|
| phone | When requested | When requested | When requested amd response_type `id_token` | No |
|
||||||
| phone_verified | When requested | When requested | When requested amd response_type `id_token` | No |
|
| phone_verified | When requested | When requested | When requested amd response_type `id_token` | No |
|
||||||
| preferred_username (username when Introspect ) | When requested | When requested | Yes | No |
|
| preferred_username (username when Introspect) | When requested | When requested | Yes | No |
|
||||||
| sub | Yes | Yes | Yes | When JWT |
|
| sub | Yes | Yes | Yes | When JWT |
|
||||||
| urn:zitadel:iam:org:domain:primary:{domainname} | When requested | When requested | When requested | When JWT and requested |
|
| urn:zitadel:iam:org:domain:primary:{domainname} | When requested | When requested | When requested | When JWT and requested |
|
||||||
| urn:zitadel:iam:org:project:roles:{rolename} | When requested | When requested | When requested or configured | When JWT and requested or configured |
|
| urn:zitadel:iam:org:project:roles:{rolename} | When requested | When requested | When requested or configured | When JWT and requested or configured |
|
||||||
| urn:zitadel:iam:user:metadata | When requested | When requested | When requested | When JWT and requested |
|
| urn:zitadel:iam:user:metadata | When requested | When requested | When requested | When JWT and requested |
|
||||||
| urn:zitadel:iam:user:resourceowner:id | When requested | When requested | When requested | When JWT and requested |
|
| urn:zitadel:iam:user:resourceowner:id | When requested | When requested | When requested | When JWT and requested |
|
||||||
| urn:zitadel:iam:user:resourceowner:name | When requested | When requested | When requested | When JWT and requested |
|
| urn:zitadel:iam:user:resourceowner:name | When requested | When requested | When requested | When JWT and requested |
|
||||||
| urn:zitadel:iam:user:resourceowner:primary_domain | When requested | When requested | When requested | When JWT and requested |
|
| urn:zitadel:iam:user:resourceowner:primary_domain | When requested | When requested | When requested | When JWT and requested |
|
||||||
|
|
||||||
## Standard Claims
|
## Standard Claims
|
||||||
|
|
||||||
@ -42,21 +44,24 @@ Please check below the matrix for an overview where which scope is asserted.
|
|||||||
| acr | TBA | TBA |
|
| acr | TBA | TBA |
|
||||||
| address | `Teufener Strasse 19, 9000 St. Gallen` | TBA |
|
| address | `Teufener Strasse 19, 9000 St. Gallen` | TBA |
|
||||||
| amr | `pwd mfa` | Authentication Method References as defined in [RFC8176](https://tools.ietf.org/html/rfc8176) |
|
| amr | `pwd mfa` | Authentication Method References as defined in [RFC8176](https://tools.ietf.org/html/rfc8176) |
|
||||||
| aud | `69234237810729019` | By default all client id's and the project id is included |
|
| aud | `69234237810729019` | The audience of the token, by default all client id's and the project id are included |
|
||||||
| auth_time | `1311280969` | Unix time of the authentication |
|
| auth_time | `1311280969` | Unix time of the authentication |
|
||||||
| azp | `69234237810729234` | Client id of the client who requested the token |
|
| azp | `69234237810729234` | Client id of the client who requested the token |
|
||||||
| email | `road.runner@acme.ch` | Email Address of the subject |
|
| email | `road.runner@acme.ch` | Email Address of the subject |
|
||||||
| email_verified | `true` | Boolean if the email was verified by ZITADEL |
|
| email_verified | `true` | Boolean if the email was verified by ZITADEL |
|
||||||
| exp | `1311281970` | Time the token expires as unix time |
|
| exp | `1311281970` | Time the token expires (as unix time) |
|
||||||
| family_name | `Runner` | The subjects family name |
|
| family_name | `Runner` | The subjects family name |
|
||||||
| gender | `other` | Gender of the subject |
|
| gender | `other` | Gender of the subject |
|
||||||
| given_name | `Road` | Given name of the subject |
|
| given_name | `Road` | Given name of the subject |
|
||||||
| iat | `1311280970` | Issued at time of the token as unix time |
|
| iat | `1311280970` | Time of the token was issued at (as unix time) |
|
||||||
| iss | `{your_domain}` | Issuing domain of a token |
|
| iss | `{your_domain}` | Issuing domain of a token |
|
||||||
|
| jti | `69234237813329048` | Unique id of the token |
|
||||||
| locale | `en` | Language from the subject |
|
| locale | `en` | Language from the subject |
|
||||||
| name | `Road Runner` | The subjects full name |
|
| name | `Road Runner` | The subjects full name |
|
||||||
|
| nbf | `1311280970` | Time the token must not be used before (as unix time) |
|
||||||
| nonce | `blQtVEJHNTF0WHhFQmhqZ0RqeHJsdzdkd2d...` | The nonce provided by the client |
|
| nonce | `blQtVEJHNTF0WHhFQmhqZ0RqeHJsdzdkd2d...` | The nonce provided by the client |
|
||||||
| phone | `+41 79 XXX XX XX` | Phone number provided by the user |
|
| phone | `+41 79 XXX XX XX` | Phone number provided by the user |
|
||||||
|
| phone_verified | `true` | Boolean if the phone was verified by ZITADEL |
|
||||||
| preferred_username | `road.runner@acme.caos.ch` | ZITADEL's login name of the user. Consist of `username@primarydomain` |
|
| preferred_username | `road.runner@acme.caos.ch` | ZITADEL's login name of the user. Consist of `username@primarydomain` |
|
||||||
| sub | `77776025198584418` | Subject ID of the user |
|
| sub | `77776025198584418` | Subject ID of the user |
|
||||||
|
|
||||||
|
@ -382,9 +382,18 @@ is active and the requesting client is part of the token audience.
|
|||||||
|
|
||||||
If `active` is **true**, further information will be provided:
|
If `active` is **true**, further information will be provided:
|
||||||
|
|
||||||
| Property | Description |
|
| Property | Description |
|
||||||
| --------- | ---------------------------------------------------- |
|
|------------|------------------------------------------------------------------------|
|
||||||
| scope | Space delimited list of scopes granted to the token. |
|
| aud | The audience of the token |
|
||||||
|
| client_id | The client_id of the application the token was issued to |
|
||||||
|
| exp | Time the token expires (as unix time) |
|
||||||
|
| iat | Time of the token was issued at (as unix time) |
|
||||||
|
| iss | Issuer of the token |
|
||||||
|
| jti | Unique id of the token |
|
||||||
|
| nbf | Time the token must not be used before (as unix time) |
|
||||||
|
| scope | Space delimited list of scopes granted to the token |
|
||||||
|
| token_type | Type of the inspected token. Value is always `Bearer` |
|
||||||
|
| username | ZITADEL's login name of the user. Consist of `username@primarydomain` |
|
||||||
|
|
||||||
Additionally and depending on the granted scopes, information about the authorized user is provided.
|
Additionally and depending on the granted scopes, information about the authorized user is provided.
|
||||||
Check the [Claims](claims) page if a specific claims might be returned and for detailed description.
|
Check the [Claims](claims) page if a specific claims might be returned and for detailed description.
|
||||||
|
@ -41,7 +41,7 @@ The primary domain scope will restrict the login to your organization, so only u
|
|||||||
|
|
||||||
See the following link as an example. Users will be able to register and login to the organization that verified the @caos.ch domain only.
|
See the following link as an example. Users will be able to register and login to the organization that verified the @caos.ch domain only.
|
||||||
```
|
```
|
||||||
https://accounts.zitadel.ch/oauth/v2/authorize?client_id=69234247558357051%40zitadel&scope=openid%20profile%20urn%3Azitadel%3Aiam%3Aorg%3Adomain%3Aprimary%3Acaos.ch&redirect_uri=https%3A%2F%2Fconsole.zitadel.ch%2Fauth%2Fcallback&state=testd&response_type=code&nonce=test&code_challenge=UY30LKMy4bZFwF7Oyk6BpJemzVblLRf0qmFT8rskUW0
|
https://{your_domain.zitadel.cloud}/oauth/v2/authorize?client_id=69234247558357051%40zitadel&scope=openid%20profile%20urn%3Azitadel%3Aiam%3Aorg%3Adomain%3Aprimary%3Acaos.ch&redirect_uri=https%3A%2F%2Fconsole.zitadel.ch%2Fauth%2Fcallback&state=testd&response_type=code&nonce=test&code_challenge=UY30LKMy4bZFwF7Oyk6BpJemzVblLRf0qmFT8rskUW0
|
||||||
```
|
```
|
||||||
|
|
||||||
:::info
|
:::info
|
||||||
|
@ -4,10 +4,9 @@ title: Configure
|
|||||||
|
|
||||||
import Tabs from "@theme/Tabs";
|
import Tabs from "@theme/Tabs";
|
||||||
import TabItem from "@theme/TabItem";
|
import TabItem from "@theme/TabItem";
|
||||||
import LinuxUnix from './linuxunix.mdx'
|
import LinuxUnix from './_linuxunix.mdx'
|
||||||
import Windows from './windows.mdx'
|
import Compose from './_compose.mdx'
|
||||||
import Compose from './compose.mdx'
|
import Helm from './_helm.mdx'
|
||||||
import Helm from './helm.mdx'
|
|
||||||
|
|
||||||
# Configure ZITADEL
|
# Configure ZITADEL
|
||||||
|
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
<!-- TODO: Content -->
|
|
||||||
Coming soon
|
|
@ -4,14 +4,13 @@ title: Run
|
|||||||
|
|
||||||
import Tabs from "@theme/Tabs";
|
import Tabs from "@theme/Tabs";
|
||||||
import TabItem from "@theme/TabItem";
|
import TabItem from "@theme/TabItem";
|
||||||
import Linux from './linux.mdx'
|
import Linux from './_linux.mdx'
|
||||||
import MacOS from './macos.mdx'
|
import MacOS from './_macos.mdx'
|
||||||
import Windows from './windows.mdx'
|
import Compose from './_compose.mdx'
|
||||||
import Compose from './compose.mdx'
|
import Helm from './_helm.mdx'
|
||||||
import Helm from './helm.mdx'
|
import Knative from './_knative.mdx'
|
||||||
import Knative from './knative.mdx'
|
import NextSelfHosted from './_nextselfhosted.mdx'
|
||||||
import NextSelfHosted from './nextselfhosted.mdx'
|
import DefaultUser from './_defaultuser.mdx'
|
||||||
import DefaultUser from './defaultuser.mdx'
|
|
||||||
|
|
||||||
# Run ZITADEL
|
# Run ZITADEL
|
||||||
|
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
<!-- TODO: Content -->
|
|
||||||
Coming soon
|
|
@ -85,6 +85,16 @@ module.exports = {
|
|||||||
label: "GitHub",
|
label: "GitHub",
|
||||||
position: "right",
|
position: "right",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
href: "https://zitadel.com/chat",
|
||||||
|
label: "Chat",
|
||||||
|
position: "right",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Discussions",
|
||||||
|
position: "right",
|
||||||
|
href: "https://github.com/zitadel/zitadel/discussions",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
footer: {
|
footer: {
|
||||||
|
9
go.mod
9
go.mod
@ -17,7 +17,6 @@ require (
|
|||||||
github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d
|
github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d
|
||||||
github.com/duo-labs/webauthn v0.0.0-20211216225436-9a12cd078b8a
|
github.com/duo-labs/webauthn v0.0.0-20211216225436-9a12cd078b8a
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.6.2
|
github.com/envoyproxy/protoc-gen-validate v0.6.2
|
||||||
github.com/getsentry/sentry-go v0.11.0
|
|
||||||
github.com/golang/glog v1.0.0
|
github.com/golang/glog v1.0.0
|
||||||
github.com/golang/mock v1.6.0
|
github.com/golang/mock v1.6.0
|
||||||
github.com/golang/protobuf v1.5.2
|
github.com/golang/protobuf v1.5.2
|
||||||
@ -48,8 +47,8 @@ require (
|
|||||||
github.com/stretchr/testify v1.7.1
|
github.com/stretchr/testify v1.7.1
|
||||||
github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203
|
github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203
|
||||||
github.com/ttacon/libphonenumber v1.2.1
|
github.com/ttacon/libphonenumber v1.2.1
|
||||||
github.com/zitadel/logging v0.3.3
|
github.com/zitadel/logging v0.3.4
|
||||||
github.com/zitadel/oidc/v2 v2.0.0-dynamic-issuer.3
|
github.com/zitadel/oidc/v2 v2.0.0-dynamic-issuer.4
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.27.0
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.27.0
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.27.0
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.27.0
|
||||||
go.opentelemetry.io/otel v1.2.0
|
go.opentelemetry.io/otel v1.2.0
|
||||||
@ -154,7 +153,7 @@ require (
|
|||||||
github.com/prometheus/procfs v0.6.0 // indirect
|
github.com/prometheus/procfs v0.6.0 // indirect
|
||||||
github.com/rs/xid v1.2.1 // indirect
|
github.com/rs/xid v1.2.1 // indirect
|
||||||
github.com/satori/go.uuid v1.2.0 // indirect
|
github.com/satori/go.uuid v1.2.0 // indirect
|
||||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||||
github.com/spf13/afero v1.8.1 // indirect
|
github.com/spf13/afero v1.8.1 // indirect
|
||||||
github.com/spf13/cast v1.4.1 // indirect
|
github.com/spf13/cast v1.4.1 // indirect
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
@ -170,7 +169,7 @@ require (
|
|||||||
go.opentelemetry.io/proto/otlp v0.10.0 // indirect
|
go.opentelemetry.io/proto/otlp v0.10.0 // indirect
|
||||||
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 // indirect
|
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 // indirect
|
||||||
golang.org/x/mod v0.5.1 // indirect
|
golang.org/x/mod v0.5.1 // indirect
|
||||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||||
google.golang.org/api v0.63.0 // indirect
|
google.golang.org/api v0.63.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
|
103
go.sum
103
go.sum
@ -53,20 +53,16 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f
|
|||||||
cloud.google.com/go/trace v1.0.0 h1:laKx2y7IWMjguCe5zZx6n7qLtREk4kyE69SXVC0VSN8=
|
cloud.google.com/go/trace v1.0.0 h1:laKx2y7IWMjguCe5zZx6n7qLtREk4kyE69SXVC0VSN8=
|
||||||
cloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A=
|
cloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A=
|
||||||
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/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
|
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
|
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
|
||||||
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
|
|
||||||
github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo=
|
|
||||||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||||
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.0.0 h1:38fNtfhHY6bs22b/D6+hDzO6JR0rDzpGPD36dY2uPL4=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.0.0 h1:38fNtfhHY6bs22b/D6+hDzO6JR0rDzpGPD36dY2uPL4=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.0.0/go.mod h1:jE23wM1jvwSKgdGcoOkj5j9n1VWtncW36pL2bK1JU+0=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.0.0/go.mod h1:jE23wM1jvwSKgdGcoOkj5j9n1VWtncW36pL2bK1JU+0=
|
||||||
github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY=
|
|
||||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||||
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||||
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||||
@ -78,14 +74,12 @@ github.com/Masterminds/squirrel v1.5.2 h1:UiOEi2ZX4RCSkpiNDQN5kro/XIBpSRk9iTqdIR
|
|||||||
github.com/Masterminds/squirrel v1.5.2/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
github.com/Masterminds/squirrel v1.5.2/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
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/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||||
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
|
|
||||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
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/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||||
github.com/VictoriaMetrics/fastcache v1.8.0 h1:ybZqS7kRy8YVzYsI09GLzQhs7iqS6cOEH2avtknD1SU=
|
github.com/VictoriaMetrics/fastcache v1.8.0 h1:ybZqS7kRy8YVzYsI09GLzQhs7iqS6cOEH2avtknD1SU=
|
||||||
github.com/VictoriaMetrics/fastcache v1.8.0/go.mod h1:n7Sl+ioh/HlWeYHLSIBIE8TcZFHg/+xgvomWSS5xuEE=
|
github.com/VictoriaMetrics/fastcache v1.8.0/go.mod h1:n7Sl+ioh/HlWeYHLSIBIE8TcZFHg/+xgvomWSS5xuEE=
|
||||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
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/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||||
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
|
||||||
github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY=
|
github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY=
|
||||||
github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk=
|
github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk=
|
||||||
github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b h1:slYM766cy2nI3BwyRiyQj/Ud48djTMtMebDqepE95rw=
|
github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b h1:slYM766cy2nI3BwyRiyQj/Ud48djTMtMebDqepE95rw=
|
||||||
@ -103,7 +97,6 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd
|
|||||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
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/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/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-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||||
github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
||||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||||
@ -112,7 +105,6 @@ github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6l
|
|||||||
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
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.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||||
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
|
|
||||||
github.com/benbjohnson/clock v1.2.0 h1:9Re3G2TWxkE06LdMWMpcY6KV81GLXMGiYpPYUPkFAws=
|
github.com/benbjohnson/clock v1.2.0 h1:9Re3G2TWxkE06LdMWMpcY6KV81GLXMGiYpPYUPkFAws=
|
||||||
github.com/benbjohnson/clock v1.2.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
github.com/benbjohnson/clock v1.2.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
@ -163,9 +155,6 @@ github.com/cockroachdb/cockroach-go/v2 v2.2.4 h1:VuiBJKut2Imgrzl+TNk+U5+GxLOh3hn
|
|||||||
github.com/cockroachdb/cockroach-go/v2 v2.2.4/go.mod h1:u3MiKYGupPPjkn3ozknpMUpxPaNLTFWAya419/zv6eI=
|
github.com/cockroachdb/cockroach-go/v2 v2.2.4/go.mod h1:u3MiKYGupPPjkn3ozknpMUpxPaNLTFWAya419/zv6eI=
|
||||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
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/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||||
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
|
|
||||||
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-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
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-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-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
@ -173,7 +162,6 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
|
|||||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/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/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||||
@ -187,9 +175,7 @@ github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6RO
|
|||||||
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||||
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I=
|
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I=
|
||||||
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE=
|
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE=
|
||||||
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
|
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
|
||||||
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 h1:Izz0+t1Z5nI16/II7vuEo/nHjodOg0p7+OiDpjX5t1E=
|
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 h1:Izz0+t1Z5nI16/II7vuEo/nHjodOg0p7+OiDpjX5t1E=
|
||||||
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||||
github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
|
github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
|
||||||
@ -227,7 +213,6 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m
|
|||||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
github.com/eapache/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/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/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||||
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
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.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.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
@ -244,12 +229,9 @@ github.com/envoyproxy/protoc-gen-validate v0.6.2 h1:JiO+kJTpmYGjEodY7O1Zk8oZcNz1
|
|||||||
github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
|
github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
|
||||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
|
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/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||||
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
|
|
||||||
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
|
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
|
||||||
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o=
|
github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o=
|
||||||
github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
@ -260,17 +242,12 @@ github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWp
|
|||||||
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
||||||
github.com/fxamacker/cbor/v2 v2.2.0 h1:6eXqdDDe588rSYAi1HfZKbx6YYQO4mxQ9eC6xYpU/JQ=
|
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/fxamacker/cbor/v2 v2.2.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
|
||||||
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
|
|
||||||
github.com/getsentry/sentry-go v0.11.0 h1:qro8uttJGvNAMr5CLcFI9CHR0aDzXl0Vs3Pmw/oTPg8=
|
|
||||||
github.com/getsentry/sentry-go v0.11.0/go.mod h1:KBQIxiZAetw62Cj8Ri964vAEWVdgfaUCn30Q3bCvANo=
|
|
||||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
github.com/gin-gonic/gin v1.7.4 h1:QmUZXrvJ9qZ3GfWvQ+2wnW/1ePrTEJqPKMYEU3lD/DM=
|
github.com/gin-gonic/gin v1.7.4 h1:QmUZXrvJ9qZ3GfWvQ+2wnW/1ePrTEJqPKMYEU3lD/DM=
|
||||||
github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||||
github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
|
||||||
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
|
|
||||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||||
github.com/go-errors/errors v1.0.2 h1:xMxH9j2fNg/L4hLn/4y3M0IUsn0M6Wbu/Uh9QlOfBh4=
|
github.com/go-errors/errors v1.0.2 h1:xMxH9j2fNg/L4hLn/4y3M0IUsn0M6Wbu/Uh9QlOfBh4=
|
||||||
github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
||||||
@ -284,7 +261,6 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb
|
|||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
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-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||||
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
|
|
||||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||||
@ -295,7 +271,6 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+
|
|||||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||||
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
|
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
|
||||||
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
||||||
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
|
||||||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
|
github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
|
||||||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
|
github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
|
||||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
@ -371,7 +346,6 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8l
|
|||||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
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 h1:Yf1aXowfZ2nuboBsg7iYGLmwsOARdV86pfH3g95wXmE=
|
||||||
@ -506,17 +480,11 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
|
|||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/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.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||||
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
|
|
||||||
github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ=
|
github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ=
|
||||||
github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8=
|
github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
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/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||||
github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI=
|
|
||||||
github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0=
|
|
||||||
github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk=
|
|
||||||
github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g=
|
|
||||||
github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw=
|
|
||||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
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.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||||
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||||
@ -586,14 +554,8 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7
|
|||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
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/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||||
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
|
|
||||||
github.com/k3a/html2text v1.0.8 h1:rVanLhKilpnJUJs/CNKWzMC4YaQINGxK0rSG8ssmnV0=
|
github.com/k3a/html2text v1.0.8 h1:rVanLhKilpnJUJs/CNKWzMC4YaQINGxK0rSG8ssmnV0=
|
||||||
github.com/k3a/html2text v1.0.8/go.mod h1:ieEXykM67iT8lTvEWBh6fhpH4B23kB9OMKPdIBmgUqA=
|
github.com/k3a/html2text v1.0.8/go.mod h1:ieEXykM67iT8lTvEWBh6fhpH4B23kB9OMKPdIBmgUqA=
|
||||||
github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8=
|
|
||||||
github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE=
|
|
||||||
github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE=
|
|
||||||
github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro=
|
|
||||||
github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8=
|
|
||||||
github.com/kevinburke/go-types v0.0.0-20210723172823-2deba1f80ba7 h1:K8qael4LemsmJCGt+ccI8b0fCNFDttmEu3qtpFt3G0M=
|
github.com/kevinburke/go-types v0.0.0-20210723172823-2deba1f80ba7 h1:K8qael4LemsmJCGt+ccI8b0fCNFDttmEu3qtpFt3G0M=
|
||||||
github.com/kevinburke/go-types v0.0.0-20210723172823-2deba1f80ba7/go.mod h1:/Pk5i/SqYdYv1cie5wGwoZ4P6TpgMi+Yf58mtJSHdOw=
|
github.com/kevinburke/go-types v0.0.0-20210723172823-2deba1f80ba7/go.mod h1:/Pk5i/SqYdYv1cie5wGwoZ4P6TpgMi+Yf58mtJSHdOw=
|
||||||
github.com/kevinburke/rest v0.0.0-20210506044642-5611499aa33c h1:hnbwWED5rIu+UaMkLR3JtnscMVGqp35lfzQwLuZAAUY=
|
github.com/kevinburke/rest v0.0.0-20210506044642-5611499aa33c h1:hnbwWED5rIu+UaMkLR3JtnscMVGqp35lfzQwLuZAAUY=
|
||||||
@ -603,14 +565,11 @@ github.com/kevinburke/twilio-go v0.0.0-20210327194925-1623146bcf73/go.mod h1:Fm9
|
|||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
|
||||||
github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
|
||||||
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||||
github.com/klauspost/compress v1.14.2 h1:S0OHlFk/Gbon/yauFJ4FfJJF5V0fc5HbBTJazi28pRw=
|
github.com/klauspost/compress v1.14.2 h1:S0OHlFk/Gbon/yauFJ4FfJJF5V0fc5HbBTJazi28pRw=
|
||||||
github.com/klauspost/compress v1.14.2/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
github.com/klauspost/compress v1.14.2/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||||
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
|
||||||
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s=
|
github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s=
|
||||||
github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
|
github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
|
||||||
@ -628,8 +587,6 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
|||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
|
|
||||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
|
||||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=
|
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=
|
||||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
|
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
|
||||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk=
|
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk=
|
||||||
@ -653,7 +610,6 @@ github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69
|
|||||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||||
github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
|
github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
|
||||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
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/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
|
github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
|
||||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
@ -679,12 +635,9 @@ github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71
|
|||||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
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/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
|
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||||
github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8=
|
|
||||||
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
|
|
||||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||||
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
||||||
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
||||||
@ -717,7 +670,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
|
|||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
|
|
||||||
github.com/muesli/clusters v0.0.0-20180605185049-a07a36e67d36/go.mod h1:mw5KDqUj0eLj/6DUNINLVJNoPTFkEuGMHtJsXLviLkY=
|
github.com/muesli/clusters v0.0.0-20180605185049-a07a36e67d36/go.mod h1:mw5KDqUj0eLj/6DUNINLVJNoPTFkEuGMHtJsXLviLkY=
|
||||||
github.com/muesli/clusters v0.0.0-20200529215643-2700303c1762 h1:p4A2Jx7Lm3NV98VRMKlyWd3nqf8obft8NfXlAUmqd3I=
|
github.com/muesli/clusters v0.0.0-20200529215643-2700303c1762 h1:p4A2Jx7Lm3NV98VRMKlyWd3nqf8obft8NfXlAUmqd3I=
|
||||||
github.com/muesli/clusters v0.0.0-20200529215643-2700303c1762/go.mod h1:mw5KDqUj0eLj/6DUNINLVJNoPTFkEuGMHtJsXLviLkY=
|
github.com/muesli/clusters v0.0.0-20200529215643-2700303c1762/go.mod h1:mw5KDqUj0eLj/6DUNINLVJNoPTFkEuGMHtJsXLviLkY=
|
||||||
@ -744,9 +696,7 @@ github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQ
|
|||||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
github.com/onsi/ginkgo v1.6.0/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.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
|
||||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
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/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||||
@ -760,14 +710,11 @@ github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIw
|
|||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
|
||||||
github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM=
|
github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM=
|
||||||
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||||
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
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/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||||
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
|
|
||||||
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
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.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
@ -825,19 +772,15 @@ 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/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.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
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/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
|
||||||
github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
|
github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
|
||||||
github.com/sagikazarmark/crypt v0.4.0/go.mod h1:ALv2SRj7GxYV4HO9elxH9nS6M9gW+xDNxqmyJ6RfDFM=
|
github.com/sagikazarmark/crypt v0.4.0/go.mod h1:ALv2SRj7GxYV4HO9elxH9nS6M9gW+xDNxqmyJ6RfDFM=
|
||||||
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
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 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
|
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
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-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-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||||
@ -847,8 +790,9 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
|
|||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
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.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
|
||||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
|
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||||
|
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||||
@ -858,26 +802,20 @@ github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJ
|
|||||||
github.com/sony/sonyflake v1.0.0 h1:MpU6Ro7tfXwgn2l5eluf9xQvQJDROTBImNCfRXn/YeM=
|
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/sony/sonyflake v1.0.0/go.mod h1:Jv3cfhf/UFtolOTTRd3q4Nl6ENqM+KfyZ5PseKfZGF4=
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
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.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
|
github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
|
||||||
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||||
github.com/spf13/afero v1.8.1 h1:izYHOT71f9iZ7iq37Uqjael60/vYC6vMtzedudZ0zEk=
|
github.com/spf13/afero v1.8.1 h1:izYHOT71f9iZ7iq37Uqjael60/vYC6vMtzedudZ0zEk=
|
||||||
github.com/spf13/afero v1.8.1/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
|
github.com/spf13/afero v1.8.1/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
|
||||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
|
||||||
github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
|
github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
|
||||||
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
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 v1.3.0 h1:R7cSvGu+Vv+qX0gW5R/85dx2kmmJT5z5NM8ifdYjdn0=
|
github.com/spf13/cobra v1.3.0 h1:R7cSvGu+Vv+qX0gW5R/85dx2kmmJT5z5NM8ifdYjdn0=
|
||||||
github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
|
github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
|
||||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||||
github.com/spf13/pflag v1.0.1/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 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
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.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM=
|
github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM=
|
||||||
github.com/spf13/viper v1.10.1 h1:nuJZuYpG7gTj/XqiUwg8bA0cp1+M2mC3J4g5luUYBKk=
|
github.com/spf13/viper v1.10.1 h1:nuJZuYpG7gTj/XqiUwg8bA0cp1+M2mC3J4g5luUYBKk=
|
||||||
github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU=
|
github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU=
|
||||||
@ -907,31 +845,17 @@ github.com/ttacon/libphonenumber v1.2.1/go.mod h1:E0TpmdVMq5dyVlQ7oenAkhsLu86OkU
|
|||||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||||
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
|
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
|
||||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
|
||||||
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
||||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
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.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
|
|
||||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
|
||||||
github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
|
|
||||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
|
||||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
|
||||||
github.com/wcharczuk/go-chart/v2 v2.1.0 h1:tY2slqVQ6bN+yHSnDYwZebLQFkphK4WNrVwnt7CJZ2I=
|
github.com/wcharczuk/go-chart/v2 v2.1.0 h1:tY2slqVQ6bN+yHSnDYwZebLQFkphK4WNrVwnt7CJZ2I=
|
||||||
github.com/wcharczuk/go-chart/v2 v2.1.0/go.mod h1:yx7MvAVNcP/kN9lKXM/NTce4au4DFN99j6i1OwDclNA=
|
github.com/wcharczuk/go-chart/v2 v2.1.0/go.mod h1:yx7MvAVNcP/kN9lKXM/NTce4au4DFN99j6i1OwDclNA=
|
||||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
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/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
|
||||||
github.com/xrash/smetrics v0.0.0-20200730060457-89a2a8a1fb0b h1:tnWgqoOBmInkt5pbLjagwNVjjT4RdJhFHzL1ebCSRh8=
|
github.com/xrash/smetrics v0.0.0-20200730060457-89a2a8a1fb0b h1:tnWgqoOBmInkt5pbLjagwNVjjT4RdJhFHzL1ebCSRh8=
|
||||||
github.com/xrash/smetrics v0.0.0-20200730060457-89a2a8a1fb0b/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
github.com/xrash/smetrics v0.0.0-20200730060457-89a2a8a1fb0b/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||||
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI=
|
|
||||||
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
|
|
||||||
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
|
|
||||||
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
|
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
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.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
@ -939,10 +863,10 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
|
|||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||||
github.com/zitadel/logging v0.3.3 h1:/nAoki9HFJK+qMLBVY5Jhbfp/6o3YLK49Tw5j2oRhjM=
|
github.com/zitadel/logging v0.3.4 h1:9hZsTjMMTE3X2LUi0xcF9Q9EdLo+FAezeu52ireBbHM=
|
||||||
github.com/zitadel/logging v0.3.3/go.mod h1:aPpLQhE+v6ocNK0TWrBrd363hZ95KcI17Q1ixAQwZF0=
|
github.com/zitadel/logging v0.3.4/go.mod h1:aPpLQhE+v6ocNK0TWrBrd363hZ95KcI17Q1ixAQwZF0=
|
||||||
github.com/zitadel/oidc/v2 v2.0.0-dynamic-issuer.3 h1:Z0WrhhjPLrbywD+6226Ca7Mvt9VKAU3J/ojYq24CUEY=
|
github.com/zitadel/oidc/v2 v2.0.0-dynamic-issuer.4 h1:llGVhiHOuI2SXF6yR9s5podxe8n7Md0lpo/9cr37AkU=
|
||||||
github.com/zitadel/oidc/v2 v2.0.0-dynamic-issuer.3/go.mod h1:uoJw5Xc6HXfnQbNZiLbld9dED0/8UMu0M4gOipTRZBA=
|
github.com/zitadel/oidc/v2 v2.0.0-dynamic-issuer.4/go.mod h1:uoJw5Xc6HXfnQbNZiLbld9dED0/8UMu0M4gOipTRZBA=
|
||||||
go.etcd.io/bbolt v1.3.3/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.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||||
go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
||||||
@ -1013,7 +937,6 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
|||||||
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
|
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
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-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-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/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-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-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
@ -1025,7 +948,6 @@ golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8U
|
|||||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||||
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-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/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/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
@ -1088,7 +1010,6 @@ 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-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-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-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/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-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-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
@ -1098,7 +1019,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/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-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-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-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/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-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-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
@ -1173,7 +1093,6 @@ 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-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-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-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-20190215142949-d0b11bdaac8a/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-20190222072716-a9d3bda3a223/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=
|
||||||
@ -1184,7 +1103,6 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/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-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-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@ -1253,8 +1171,8 @@ golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
|
||||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
@ -1275,13 +1193,11 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb
|
|||||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
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-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-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20181221001348-537d06c36207/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-20190114222345-bf090417da8b/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-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-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
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-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
@ -1527,12 +1443,10 @@ 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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||||
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
|
||||||
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4=
|
gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4=
|
||||||
gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
|
||||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
|
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
|
||||||
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||||
@ -1549,7 +1463,6 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
@ -73,30 +73,26 @@ func (m *Styling) CurrentSequence(instanceID string) (uint64, error) {
|
|||||||
return sequence.CurrentSequence, nil
|
return sequence.CurrentSequence, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Styling) EventQuery() (*models.SearchQuery, error) {
|
func (m *Styling) EventQuery(instanceIDs ...string) (*models.SearchQuery, error) {
|
||||||
sequences, err := m.view.GetLatestStylingSequences()
|
sequences, err := m.view.GetLatestStylingSequences(instanceIDs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
query := models.NewSearchQuery()
|
searchQuery := models.NewSearchQuery()
|
||||||
instances := make([]string, 0)
|
|
||||||
for _, sequence := range sequences {
|
for _, sequence := range sequences {
|
||||||
for _, instance := range instances {
|
var seq uint64
|
||||||
if sequence.InstanceID == instance {
|
for _, instanceID := range instanceIDs {
|
||||||
|
if sequence.InstanceID == instanceID {
|
||||||
|
seq = sequence.CurrentSequence
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
instances = append(instances, sequence.InstanceID)
|
searchQuery.AddQuery().
|
||||||
query.AddQuery().
|
|
||||||
AggregateTypeFilter(m.AggregateTypes()...).
|
AggregateTypeFilter(m.AggregateTypes()...).
|
||||||
LatestSequenceFilter(sequence.CurrentSequence).
|
LatestSequenceFilter(seq).
|
||||||
InstanceIDFilter(sequence.InstanceID)
|
InstanceIDFilter(sequence.InstanceID)
|
||||||
}
|
}
|
||||||
return query.AddQuery().
|
return searchQuery, nil
|
||||||
AggregateTypeFilter(m.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(0).
|
|
||||||
ExcludedInstanceIDsFilter(instances...).
|
|
||||||
SearchQuery(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Styling) Reduce(event *models.Event) (err error) {
|
func (m *Styling) Reduce(event *models.Event) (err error) {
|
||||||
@ -299,7 +295,7 @@ func (m *Styling) generateColorPaletteRGBA255(hex string) map[string]string {
|
|||||||
if ok {
|
if ok {
|
||||||
palette["500"] = cssRGB(color500.RGB255())
|
palette["500"] = cssRGB(color500.RGB255())
|
||||||
}
|
}
|
||||||
|
|
||||||
color600, ok := colorful.MakeColor(gamut.Darker(defaultColor, 0.06))
|
color600, ok := colorful.MakeColor(gamut.Darker(defaultColor, 0.06))
|
||||||
if ok {
|
if ok {
|
||||||
palette["600"] = cssRGB(color600.RGB255())
|
palette["600"] = cssRGB(color600.RGB255())
|
||||||
|
@ -15,15 +15,17 @@ type SpoolerConfig struct {
|
|||||||
BulkLimit uint64
|
BulkLimit uint64
|
||||||
FailureCountUntilSkip uint64
|
FailureCountUntilSkip uint64
|
||||||
ConcurrentWorkers int
|
ConcurrentWorkers int
|
||||||
|
ConcurrentInstances int
|
||||||
Handlers handler.Configs
|
Handlers handler.Configs
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartSpooler(c SpoolerConfig, es v1.Eventstore, view *view.View, sql *sql.DB, static static.Storage) *spooler.Spooler {
|
func StartSpooler(c SpoolerConfig, es v1.Eventstore, view *view.View, sql *sql.DB, static static.Storage) *spooler.Spooler {
|
||||||
spoolerConfig := spooler.Config{
|
spoolerConfig := spooler.Config{
|
||||||
Eventstore: es,
|
Eventstore: es,
|
||||||
Locker: &locker{dbClient: sql},
|
Locker: &locker{dbClient: sql},
|
||||||
ConcurrentWorkers: c.ConcurrentWorkers,
|
ConcurrentWorkers: c.ConcurrentWorkers,
|
||||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, static),
|
ConcurrentInstances: c.ConcurrentInstances,
|
||||||
|
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, static),
|
||||||
}
|
}
|
||||||
spool := spoolerConfig.New()
|
spool := spoolerConfig.New()
|
||||||
spool.Start()
|
spool.Start()
|
||||||
|
@ -19,8 +19,8 @@ func (v *View) latestSequence(viewName, instanceID string) (*repository.CurrentS
|
|||||||
return repository.LatestSequence(v.Db, sequencesTable, viewName, instanceID)
|
return repository.LatestSequence(v.Db, sequencesTable, viewName, instanceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) latestSequences(viewName string) ([]*repository.CurrentSequence, error) {
|
func (v *View) latestSequences(viewName string, instanceIDs ...string) ([]*repository.CurrentSequence, error) {
|
||||||
return repository.LatestSequences(v.Db, sequencesTable, viewName)
|
return repository.LatestSequences(v.Db, sequencesTable, viewName, instanceIDs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) AllCurrentSequences(db string) ([]*repository.CurrentSequence, error) {
|
func (v *View) AllCurrentSequences(db string) ([]*repository.CurrentSequence, error) {
|
||||||
|
@ -27,8 +27,8 @@ func (v *View) GetLatestStylingSequence(instanceID string) (*global_view.Current
|
|||||||
return v.latestSequence(stylingTyble, instanceID)
|
return v.latestSequence(stylingTyble, instanceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) GetLatestStylingSequences() ([]*global_view.CurrentSequence, error) {
|
func (v *View) GetLatestStylingSequences(instanceIDs ...string) ([]*global_view.CurrentSequence, error) {
|
||||||
return v.latestSequences(stylingTyble)
|
return v.latestSequences(stylingTyble, instanceIDs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) ProcessedStylingSequence(event *models.Event) error {
|
func (v *View) ProcessedStylingSequence(event *models.Event) error {
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
sentryhttp "github.com/getsentry/sentry-go/http"
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/improbable-eng/grpc-web/go/grpcweb"
|
"github.com/improbable-eng/grpc-web/go/grpcweb"
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
@ -67,7 +66,6 @@ func (a *API) RegisterServer(ctx context.Context, grpcServer server.Server) erro
|
|||||||
func (a *API) RegisterHandler(prefix string, handler http.Handler) {
|
func (a *API) RegisterHandler(prefix string, handler http.Handler) {
|
||||||
prefix = strings.TrimSuffix(prefix, "/")
|
prefix = strings.TrimSuffix(prefix, "/")
|
||||||
subRouter := a.router.PathPrefix(prefix).Name(prefix).Subrouter()
|
subRouter := a.router.PathPrefix(prefix).Name(prefix).Subrouter()
|
||||||
subRouter.Use(sentryhttp.New(sentryhttp.Options{}).Handle)
|
|
||||||
subRouter.PathPrefix("").Handler(http.StripPrefix(prefix, handler))
|
subRouter.PathPrefix("").Handler(http.StripPrefix(prefix, handler))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
sentryhttp "github.com/getsentry/sentry-go/http"
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
|
|
||||||
@ -89,7 +88,7 @@ func NewHandler(commands *command.Commands, verifier *authz.TokenVerifier, authC
|
|||||||
|
|
||||||
verifier.RegisterServer("Assets-API", "assets", AssetsService_AuthMethods)
|
verifier.RegisterServer("Assets-API", "assets", AssetsService_AuthMethods)
|
||||||
router := mux.NewRouter()
|
router := mux.NewRouter()
|
||||||
router.Use(sentryhttp.New(sentryhttp.Options{}).Handle, instanceInterceptor)
|
router.Use(instanceInterceptor)
|
||||||
RegisterRoutes(router, h)
|
RegisterRoutes(router, h)
|
||||||
router.PathPrefix("/{owner}").Methods("GET").HandlerFunc(DownloadHandleFunc(h, h.GetFile()))
|
router.PathPrefix("/{owner}").Methods("GET").HandlerFunc(DownloadHandleFunc(h, h.GetFile()))
|
||||||
return http_util.CopyHeadersToContext(http_mw.CORSInterceptor(router))
|
return http_util.CopyHeadersToContext(http_mw.CORSInterceptor(router))
|
||||||
@ -117,6 +116,10 @@ func UploadHandleFunc(s AssetsService, uploader Uploader) func(http.ResponseWrit
|
|||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
ctxData := authz.GetCtxData(ctx)
|
ctxData := authz.GetCtxData(ctx)
|
||||||
err := r.ParseMultipartForm(maxMemory)
|
err := r.ParseMultipartForm(maxMemory)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
file, handler, err := r.FormFile(paramFile)
|
file, handler, err := r.FormFile(paramFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
@ -68,12 +68,12 @@ func (s *Server) UpdateCustomDomainPolicy(ctx context.Context, req *admin_pb.Upd
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) ResetCustomDomainPolicyTo(ctx context.Context, req *admin_pb.ResetCustomDomainPolicyToDefaultRequest) (*admin_pb.ResetCustomDomainPolicyToDefaultResponse, error) {
|
func (s *Server) ResetCustomDomainPolicyToDefault(ctx context.Context, req *admin_pb.ResetCustomDomainPolicyToDefaultRequest) (*admin_pb.ResetCustomDomainPolicyToDefaultResponse, error) {
|
||||||
err := s.command.RemoveOrgDomainPolicy(ctx, req.OrgId)
|
details, err := s.command.RemoveOrgDomainPolicy(ctx, req.OrgId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return nil, nil //TOOD: return data
|
return &admin_pb.ResetCustomDomainPolicyToDefaultResponse{Details: object.DomainToChangeDetailsPb(details)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func domainPolicyToDomain(userLoginMustBeDomain, validateOrgDomains, smtpSenderAddressMatchesInstanceDomain bool) *domain.DomainPolicy {
|
func domainPolicyToDomain(userLoginMustBeDomain, validateOrgDomains, smtpSenderAddressMatchesInstanceDomain bool) *domain.DomainPolicy {
|
||||||
@ -161,6 +161,14 @@ func (s *Server) GetCustomOrgIAMPolicy(ctx context.Context, req *admin_pb.GetCus
|
|||||||
return &admin_pb.GetCustomOrgIAMPolicyResponse{Policy: policy_grpc.DomainPolicyToOrgIAMPb(policy)}, nil
|
return &admin_pb.GetCustomOrgIAMPolicyResponse{Policy: policy_grpc.DomainPolicyToOrgIAMPb(policy)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) ResetCustomOrgIAMPolicyToDefault(ctx context.Context, req *admin_pb.ResetCustomOrgIAMPolicyToDefaultRequest) (*admin_pb.ResetCustomOrgIAMPolicyToDefaultResponse, error) {
|
||||||
|
details, err := s.command.RemoveOrgDomainPolicy(ctx, req.OrgId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &admin_pb.ResetCustomOrgIAMPolicyToDefaultResponse{Details: object.DomainToChangeDetailsPb(details)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func updateOrgIAMPolicyToDomain(req *admin_pb.UpdateOrgIAMPolicyRequest) *domain.DomainPolicy {
|
func updateOrgIAMPolicyToDomain(req *admin_pb.UpdateOrgIAMPolicyRequest) *domain.DomainPolicy {
|
||||||
return &domain.DomainPolicy{
|
return &domain.DomainPolicy{
|
||||||
UserLoginMustBeDomain: req.UserLoginMustBeDomain,
|
UserLoginMustBeDomain: req.UserLoginMustBeDomain,
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
package middleware
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getsentry/sentry-go"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
"google.golang.org/grpc/status"
|
|
||||||
)
|
|
||||||
|
|
||||||
func SentryHandler() grpc.UnaryServerInterceptor {
|
|
||||||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
|
||||||
return sendErrToSentry(ctx, req, handler)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func sendErrToSentry(ctx context.Context, req interface{}, handler grpc.UnaryHandler) (interface{}, error) {
|
|
||||||
resp, err := handler(ctx, req)
|
|
||||||
code := status.Code(err)
|
|
||||||
switch code {
|
|
||||||
case codes.Canceled,
|
|
||||||
codes.Unknown,
|
|
||||||
codes.DeadlineExceeded,
|
|
||||||
codes.ResourceExhausted,
|
|
||||||
codes.Aborted,
|
|
||||||
codes.Unimplemented,
|
|
||||||
codes.Internal,
|
|
||||||
codes.Unavailable,
|
|
||||||
codes.DataLoss:
|
|
||||||
sentry.CaptureException(err)
|
|
||||||
}
|
|
||||||
return resp, err
|
|
||||||
}
|
|
@ -30,7 +30,6 @@ func CreateServer(verifier *authz.TokenVerifier, authConfig authz.Config, querie
|
|||||||
grpc_middleware.ChainUnaryServer(
|
grpc_middleware.ChainUnaryServer(
|
||||||
middleware.DefaultTracingServer(),
|
middleware.DefaultTracingServer(),
|
||||||
middleware.MetricsHandler(metricTypes, grpc_api.Probes...),
|
middleware.MetricsHandler(metricTypes, grpc_api.Probes...),
|
||||||
middleware.SentryHandler(),
|
|
||||||
middleware.NoCacheInterceptor(),
|
middleware.NoCacheInterceptor(),
|
||||||
middleware.ErrorHandler(),
|
middleware.ErrorHandler(),
|
||||||
middleware.InstanceInterceptor(queries, hostHeaderName, system_pb.SystemService_MethodPrefix),
|
middleware.InstanceInterceptor(queries, hostHeaderName, system_pb.SystemService_MethodPrefix),
|
||||||
|
@ -176,6 +176,13 @@ func (o *OPStorage) SetIntrospectionFromToken(ctx context.Context, introspection
|
|||||||
}
|
}
|
||||||
introspection.SetScopes(token.Scopes)
|
introspection.SetScopes(token.Scopes)
|
||||||
introspection.SetClientID(token.ApplicationID)
|
introspection.SetClientID(token.ApplicationID)
|
||||||
|
introspection.SetTokenType(oidc.BearerToken)
|
||||||
|
introspection.SetExpiration(token.Expiration)
|
||||||
|
introspection.SetIssuedAt(token.CreationDate)
|
||||||
|
introspection.SetNotBefore(token.CreationDate)
|
||||||
|
introspection.SetAudience(token.Audience)
|
||||||
|
introspection.SetIssuer(op.IssuerFromContext(ctx))
|
||||||
|
introspection.SetJWTID(token.ID)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ func (l *Login) handlePasswordReset(w http.ResponseWriter, r *http.Request) {
|
|||||||
l.renderInitPassword(w, r, authReq, authReq.UserID, "", err)
|
l.renderInitPassword(w, r, authReq, authReq.UserID, "", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user, err := l.query.GetUser(setContext(r.Context(), authReq.UserOrgID), false, loginName)
|
user, err := l.query.GetUser(setContext(r.Context(), authReq.UserOrgID), true, loginName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.renderPasswordResetDone(w, r, authReq, err)
|
l.renderPasswordResetDone(w, r, authReq, err)
|
||||||
return
|
return
|
||||||
|
@ -8,8 +8,10 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/auth/repository/eventsourcing/view"
|
"github.com/zitadel/zitadel/internal/auth/repository/eventsourcing/view"
|
||||||
sd "github.com/zitadel/zitadel/internal/config/systemdefaults"
|
sd "github.com/zitadel/zitadel/internal/config/systemdefaults"
|
||||||
v1 "github.com/zitadel/zitadel/internal/eventstore/v1"
|
v1 "github.com/zitadel/zitadel/internal/eventstore/v1"
|
||||||
|
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore/v1/query"
|
"github.com/zitadel/zitadel/internal/eventstore/v1/query"
|
||||||
query2 "github.com/zitadel/zitadel/internal/query"
|
query2 "github.com/zitadel/zitadel/internal/query"
|
||||||
|
"github.com/zitadel/zitadel/internal/view/repository"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Configs map[string]*Config
|
type Configs map[string]*Config
|
||||||
@ -75,3 +77,21 @@ func (h *handler) QueryLimit() uint64 {
|
|||||||
func withInstanceID(ctx context.Context, instanceID string) context.Context {
|
func withInstanceID(ctx context.Context, instanceID string) context.Context {
|
||||||
return authz.WithInstanceID(ctx, instanceID)
|
return authz.WithInstanceID(ctx, instanceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newSearchQuery(sequences []*repository.CurrentSequence, aggregateTypes []models.AggregateType, instanceIDs []string) *models.SearchQuery {
|
||||||
|
searchQuery := models.NewSearchQuery()
|
||||||
|
for _, sequence := range sequences {
|
||||||
|
var seq uint64
|
||||||
|
for _, instanceID := range instanceIDs {
|
||||||
|
if sequence.InstanceID == instanceID {
|
||||||
|
seq = sequence.CurrentSequence
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
searchQuery.AddQuery().
|
||||||
|
AggregateTypeFilter(aggregateTypes...).
|
||||||
|
LatestSequenceFilter(seq).
|
||||||
|
InstanceIDFilter(sequence.InstanceID)
|
||||||
|
}
|
||||||
|
return searchQuery
|
||||||
|
}
|
||||||
|
@ -62,31 +62,12 @@ func (i *IDPConfig) CurrentSequence(instanceID string) (uint64, error) {
|
|||||||
return sequence.CurrentSequence, nil
|
return sequence.CurrentSequence, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IDPConfig) EventQuery() (*models.SearchQuery, error) {
|
func (i *IDPConfig) EventQuery(instanceIDs ...string) (*models.SearchQuery, error) {
|
||||||
sequences, err := i.view.GetLatestIDPConfigSequences()
|
sequences, err := i.view.GetLatestIDPConfigSequences(instanceIDs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return newSearchQuery(sequences, i.AggregateTypes(), instanceIDs), nil
|
||||||
query := models.NewSearchQuery()
|
|
||||||
instances := make([]string, 0)
|
|
||||||
for _, sequence := range sequences {
|
|
||||||
for _, instance := range instances {
|
|
||||||
if sequence.InstanceID == instance {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
instances = append(instances, sequence.InstanceID)
|
|
||||||
query.AddQuery().
|
|
||||||
AggregateTypeFilter(i.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(sequence.CurrentSequence).
|
|
||||||
InstanceIDFilter(sequence.InstanceID)
|
|
||||||
}
|
|
||||||
return query.AddQuery().
|
|
||||||
AggregateTypeFilter(i.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(0).
|
|
||||||
ExcludedInstanceIDsFilter(instances...).
|
|
||||||
SearchQuery(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IDPConfig) Reduce(event *models.Event) (err error) {
|
func (i *IDPConfig) Reduce(event *models.Event) (err error) {
|
||||||
|
@ -76,30 +76,13 @@ func (i *IDPProvider) CurrentSequence(instanceID string) (uint64, error) {
|
|||||||
return sequence.CurrentSequence, nil
|
return sequence.CurrentSequence, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IDPProvider) EventQuery() (*models.SearchQuery, error) {
|
func (i *IDPProvider) EventQuery(instanceIDs ...string) (*models.SearchQuery, error) {
|
||||||
sequences, err := i.view.GetLatestIDPProviderSequences()
|
sequences, err := i.view.GetLatestIDPProviderSequences(instanceIDs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
query := es_models.NewSearchQuery()
|
|
||||||
instances := make([]string, 0)
|
return newSearchQuery(sequences, i.AggregateTypes(), instanceIDs), nil
|
||||||
for _, sequence := range sequences {
|
|
||||||
for _, instance := range instances {
|
|
||||||
if sequence.InstanceID == instance {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
instances = append(instances, sequence.InstanceID)
|
|
||||||
query.AddQuery().
|
|
||||||
AggregateTypeFilter(i.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(sequence.CurrentSequence).
|
|
||||||
InstanceIDFilter(sequence.InstanceID)
|
|
||||||
}
|
|
||||||
return query.AddQuery().
|
|
||||||
AggregateTypeFilter(i.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(0).
|
|
||||||
ExcludedInstanceIDsFilter(instances...).
|
|
||||||
SearchQuery(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IDPProvider) Reduce(event *models.Event) (err error) {
|
func (i *IDPProvider) Reduce(event *models.Event) (err error) {
|
||||||
|
@ -62,30 +62,12 @@ func (p *OrgProjectMapping) CurrentSequence(instanceID string) (uint64, error) {
|
|||||||
return sequence.CurrentSequence, nil
|
return sequence.CurrentSequence, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *OrgProjectMapping) EventQuery() (*es_models.SearchQuery, error) {
|
func (p *OrgProjectMapping) EventQuery(instanceIDs ...string) (*es_models.SearchQuery, error) {
|
||||||
sequences, err := p.view.GetLatestOrgProjectMappingSequences()
|
sequences, err := p.view.GetLatestOrgProjectMappingSequences(instanceIDs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
query := es_models.NewSearchQuery()
|
return newSearchQuery(sequences, p.AggregateTypes(), instanceIDs), nil
|
||||||
instances := make([]string, 0)
|
|
||||||
for _, sequence := range sequences {
|
|
||||||
for _, instance := range instances {
|
|
||||||
if sequence.InstanceID == instance {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
instances = append(instances, sequence.InstanceID)
|
|
||||||
query.AddQuery().
|
|
||||||
AggregateTypeFilter(p.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(sequence.CurrentSequence).
|
|
||||||
InstanceIDFilter(sequence.InstanceID)
|
|
||||||
}
|
|
||||||
return query.AddQuery().
|
|
||||||
AggregateTypeFilter(p.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(0).
|
|
||||||
ExcludedInstanceIDsFilter(instances...).
|
|
||||||
SearchQuery(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *OrgProjectMapping) Reduce(event *es_models.Event) (err error) {
|
func (p *OrgProjectMapping) Reduce(event *es_models.Event) (err error) {
|
||||||
|
@ -66,30 +66,12 @@ func (t *RefreshToken) CurrentSequence(instanceID string) (uint64, error) {
|
|||||||
return sequence.CurrentSequence, nil
|
return sequence.CurrentSequence, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RefreshToken) EventQuery() (*es_models.SearchQuery, error) {
|
func (t *RefreshToken) EventQuery(instanceIDs ...string) (*es_models.SearchQuery, error) {
|
||||||
sequences, err := t.view.GetLatestRefreshTokenSequences()
|
sequences, err := t.view.GetLatestRefreshTokenSequences(instanceIDs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
query := es_models.NewSearchQuery()
|
return newSearchQuery(sequences, t.AggregateTypes(), instanceIDs), nil
|
||||||
instances := make([]string, 0)
|
|
||||||
for _, sequence := range sequences {
|
|
||||||
for _, instance := range instances {
|
|
||||||
if sequence.InstanceID == instance {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
instances = append(instances, sequence.InstanceID)
|
|
||||||
query.AddQuery().
|
|
||||||
AggregateTypeFilter(t.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(sequence.CurrentSequence).
|
|
||||||
InstanceIDFilter(sequence.InstanceID)
|
|
||||||
}
|
|
||||||
return query.AddQuery().
|
|
||||||
AggregateTypeFilter(t.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(0).
|
|
||||||
ExcludedInstanceIDsFilter(instances...).
|
|
||||||
SearchQuery(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RefreshToken) Reduce(event *es_models.Event) (err error) {
|
func (t *RefreshToken) Reduce(event *es_models.Event) (err error) {
|
||||||
|
@ -72,30 +72,12 @@ func (p *Token) CurrentSequence(instanceID string) (uint64, error) {
|
|||||||
return sequence.CurrentSequence, nil
|
return sequence.CurrentSequence, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Token) EventQuery() (*es_models.SearchQuery, error) {
|
func (t *Token) EventQuery(instanceIDs ...string) (*es_models.SearchQuery, error) {
|
||||||
sequences, err := t.view.GetLatestTokenSequences()
|
sequences, err := t.view.GetLatestTokenSequences(instanceIDs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
query := es_models.NewSearchQuery()
|
return newSearchQuery(sequences, t.AggregateTypes(), instanceIDs), nil
|
||||||
instances := make([]string, 0)
|
|
||||||
for _, sequence := range sequences {
|
|
||||||
for _, instance := range instances {
|
|
||||||
if sequence.InstanceID == instance {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
instances = append(instances, sequence.InstanceID)
|
|
||||||
query.AddQuery().
|
|
||||||
AggregateTypeFilter(t.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(sequence.CurrentSequence).
|
|
||||||
InstanceIDFilter(sequence.InstanceID)
|
|
||||||
}
|
|
||||||
return query.AddQuery().
|
|
||||||
AggregateTypeFilter(t.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(0).
|
|
||||||
ExcludedInstanceIDsFilter(instances...).
|
|
||||||
SearchQuery(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Token) Reduce(event *es_models.Event) (err error) {
|
func (t *Token) Reduce(event *es_models.Event) (err error) {
|
||||||
|
@ -74,30 +74,12 @@ func (u *User) CurrentSequence(instanceID string) (uint64, error) {
|
|||||||
return sequence.CurrentSequence, nil
|
return sequence.CurrentSequence, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) EventQuery() (*es_models.SearchQuery, error) {
|
func (u *User) EventQuery(instanceIDs ...string) (*es_models.SearchQuery, error) {
|
||||||
sequences, err := u.view.GetLatestUserSequences()
|
sequences, err := u.view.GetLatestUserSequences(instanceIDs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
query := es_models.NewSearchQuery()
|
return newSearchQuery(sequences, u.AggregateTypes(), instanceIDs), nil
|
||||||
instances := make([]string, 0)
|
|
||||||
for _, sequence := range sequences {
|
|
||||||
for _, instance := range instances {
|
|
||||||
if sequence.InstanceID == instance {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
instances = append(instances, sequence.InstanceID)
|
|
||||||
query.AddQuery().
|
|
||||||
AggregateTypeFilter(u.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(sequence.CurrentSequence).
|
|
||||||
InstanceIDFilter(sequence.InstanceID)
|
|
||||||
}
|
|
||||||
return query.AddQuery().
|
|
||||||
AggregateTypeFilter(u.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(0).
|
|
||||||
ExcludedInstanceIDsFilter(instances...).
|
|
||||||
SearchQuery(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) Reduce(event *es_models.Event) (err error) {
|
func (u *User) Reduce(event *es_models.Event) (err error) {
|
||||||
@ -176,6 +158,7 @@ func (u *User) ProcessUser(event *es_models.Event) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
user = &view_model.UserView{}
|
||||||
for _, e := range events {
|
for _, e := range events {
|
||||||
if err = user.AppendEvent(e); err != nil {
|
if err = user.AppendEvent(e); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -198,6 +181,7 @@ func (u *User) ProcessUser(event *es_models.Event) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
user = &view_model.UserView{}
|
||||||
for _, e := range events {
|
for _, e := range events {
|
||||||
if err = user.AppendEvent(e); err != nil {
|
if err = user.AppendEvent(e); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -77,30 +77,12 @@ func (i *ExternalIDP) CurrentSequence(instanceID string) (uint64, error) {
|
|||||||
return sequence.CurrentSequence, nil
|
return sequence.CurrentSequence, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ExternalIDP) EventQuery() (*es_models.SearchQuery, error) {
|
func (i *ExternalIDP) EventQuery(instanceIDs ...string) (*es_models.SearchQuery, error) {
|
||||||
sequences, err := i.view.GetLatestExternalIDPSequences()
|
sequences, err := i.view.GetLatestExternalIDPSequences(instanceIDs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
query := es_models.NewSearchQuery()
|
return newSearchQuery(sequences, i.AggregateTypes(), instanceIDs), nil
|
||||||
instances := make([]string, 0)
|
|
||||||
for _, sequence := range sequences {
|
|
||||||
for _, instance := range instances {
|
|
||||||
if sequence.InstanceID == instance {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
instances = append(instances, sequence.InstanceID)
|
|
||||||
query.AddQuery().
|
|
||||||
AggregateTypeFilter(i.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(sequence.CurrentSequence).
|
|
||||||
InstanceIDFilter(sequence.InstanceID)
|
|
||||||
}
|
|
||||||
return query.AddQuery().
|
|
||||||
AggregateTypeFilter(i.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(0).
|
|
||||||
ExcludedInstanceIDsFilter(instances...).
|
|
||||||
SearchQuery(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ExternalIDP) Reduce(event *es_models.Event) (err error) {
|
func (i *ExternalIDP) Reduce(event *es_models.Event) (err error) {
|
||||||
|
@ -72,30 +72,12 @@ func (u *UserSession) CurrentSequence(instanceID string) (uint64, error) {
|
|||||||
return sequence.CurrentSequence, nil
|
return sequence.CurrentSequence, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserSession) EventQuery() (*models.SearchQuery, error) {
|
func (u *UserSession) EventQuery(instanceIDs ...string) (*models.SearchQuery, error) {
|
||||||
sequences, err := u.view.GetLatestUserSessionSequences()
|
sequences, err := u.view.GetLatestUserSessionSequences(instanceIDs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
query := models.NewSearchQuery()
|
return newSearchQuery(sequences, u.AggregateTypes(), instanceIDs), nil
|
||||||
instances := make([]string, 0)
|
|
||||||
for _, sequence := range sequences {
|
|
||||||
for _, instance := range instances {
|
|
||||||
if sequence.InstanceID == instance {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
instances = append(instances, sequence.InstanceID)
|
|
||||||
query.AddQuery().
|
|
||||||
AggregateTypeFilter(u.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(sequence.CurrentSequence).
|
|
||||||
InstanceIDFilter(sequence.InstanceID)
|
|
||||||
}
|
|
||||||
return query.AddQuery().
|
|
||||||
AggregateTypeFilter(u.AggregateTypes()...).
|
|
||||||
LatestSequenceFilter(0).
|
|
||||||
ExcludedInstanceIDsFilter(instances...).
|
|
||||||
SearchQuery(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserSession) Reduce(event *models.Event) (err error) {
|
func (u *UserSession) Reduce(event *models.Event) (err error) {
|
||||||
|
@ -16,15 +16,17 @@ type SpoolerConfig struct {
|
|||||||
BulkLimit uint64
|
BulkLimit uint64
|
||||||
FailureCountUntilSkip uint64
|
FailureCountUntilSkip uint64
|
||||||
ConcurrentWorkers int
|
ConcurrentWorkers int
|
||||||
|
ConcurrentInstances int
|
||||||
Handlers handler.Configs
|
Handlers handler.Configs
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartSpooler(c SpoolerConfig, es v1.Eventstore, view *view.View, client *sql.DB, systemDefaults sd.SystemDefaults, queries *query.Queries) *spooler.Spooler {
|
func StartSpooler(c SpoolerConfig, es v1.Eventstore, view *view.View, client *sql.DB, systemDefaults sd.SystemDefaults, queries *query.Queries) *spooler.Spooler {
|
||||||
spoolerConfig := spooler.Config{
|
spoolerConfig := spooler.Config{
|
||||||
Eventstore: es,
|
Eventstore: es,
|
||||||
Locker: &locker{dbClient: client},
|
Locker: &locker{dbClient: client},
|
||||||
ConcurrentWorkers: c.ConcurrentWorkers,
|
ConcurrentWorkers: c.ConcurrentWorkers,
|
||||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, systemDefaults, queries),
|
ConcurrentInstances: c.ConcurrentInstances,
|
||||||
|
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, systemDefaults, queries),
|
||||||
}
|
}
|
||||||
spool := spoolerConfig.New()
|
spool := spoolerConfig.New()
|
||||||
spool.Start()
|
spool.Start()
|
||||||
|
@ -60,8 +60,8 @@ func (v *View) GetLatestExternalIDPSequence(instanceID string) (*global_view.Cur
|
|||||||
return v.latestSequence(externalIDPTable, instanceID)
|
return v.latestSequence(externalIDPTable, instanceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) GetLatestExternalIDPSequences() ([]*global_view.CurrentSequence, error) {
|
func (v *View) GetLatestExternalIDPSequences(instanceIDs ...string) ([]*global_view.CurrentSequence, error) {
|
||||||
return v.latestSequences(externalIDPTable)
|
return v.latestSequences(externalIDPTable, instanceIDs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) ProcessedExternalIDPSequence(event *models.Event) error {
|
func (v *View) ProcessedExternalIDPSequence(event *models.Event) error {
|
||||||
|
@ -45,8 +45,8 @@ func (v *View) GetLatestIDPConfigSequence(instanceID string) (*global_view.Curre
|
|||||||
return v.latestSequence(idpConfigTable, instanceID)
|
return v.latestSequence(idpConfigTable, instanceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) GetLatestIDPConfigSequences() ([]*global_view.CurrentSequence, error) {
|
func (v *View) GetLatestIDPConfigSequences(instanceIDs ...string) ([]*global_view.CurrentSequence, error) {
|
||||||
return v.latestSequences(idpConfigTable)
|
return v.latestSequences(idpConfigTable, instanceIDs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) ProcessedIDPConfigSequence(event *models.Event) error {
|
func (v *View) ProcessedIDPConfigSequence(event *models.Event) error {
|
||||||
|
@ -65,8 +65,8 @@ func (v *View) GetLatestIDPProviderSequence(instanceID string) (*global_view.Cur
|
|||||||
return v.latestSequence(idpProviderTable, instanceID)
|
return v.latestSequence(idpProviderTable, instanceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) GetLatestIDPProviderSequences() ([]*global_view.CurrentSequence, error) {
|
func (v *View) GetLatestIDPProviderSequences(instanceIDs ...string) ([]*global_view.CurrentSequence, error) {
|
||||||
return v.latestSequences(idpProviderTable)
|
return v.latestSequences(idpProviderTable, instanceIDs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) ProcessedIDPProviderSequence(event *models.Event) error {
|
func (v *View) ProcessedIDPProviderSequence(event *models.Event) error {
|
||||||
|
@ -44,8 +44,8 @@ func (v *View) GetLatestOrgProjectMappingSequence(instanceID string) (*repositor
|
|||||||
return v.latestSequence(orgPrgojectMappingTable, instanceID)
|
return v.latestSequence(orgPrgojectMappingTable, instanceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) GetLatestOrgProjectMappingSequences() ([]*repository.CurrentSequence, error) {
|
func (v *View) GetLatestOrgProjectMappingSequences(instanceIDs ...string) ([]*repository.CurrentSequence, error) {
|
||||||
return v.latestSequences(orgPrgojectMappingTable)
|
return v.latestSequences(orgPrgojectMappingTable, instanceIDs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) ProcessedOrgProjectMappingSequence(event *models.Event) error {
|
func (v *View) ProcessedOrgProjectMappingSequence(event *models.Event) error {
|
||||||
|
@ -69,8 +69,8 @@ func (v *View) GetLatestRefreshTokenSequence(instanceID string) (*repository.Cur
|
|||||||
return v.latestSequence(refreshTokenTable, instanceID)
|
return v.latestSequence(refreshTokenTable, instanceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) GetLatestRefreshTokenSequences() ([]*repository.CurrentSequence, error) {
|
func (v *View) GetLatestRefreshTokenSequences(instanceIDs ...string) ([]*repository.CurrentSequence, error) {
|
||||||
return v.latestSequences(refreshTokenTable)
|
return v.latestSequences(refreshTokenTable, instanceIDs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) ProcessedRefreshTokenSequence(event *models.Event) error {
|
func (v *View) ProcessedRefreshTokenSequence(event *models.Event) error {
|
||||||
|
@ -19,8 +19,8 @@ func (v *View) latestSequence(viewName, instanceID string) (*repository.CurrentS
|
|||||||
return repository.LatestSequence(v.Db, sequencesTable, viewName, instanceID)
|
return repository.LatestSequence(v.Db, sequencesTable, viewName, instanceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) latestSequences(viewName string) ([]*repository.CurrentSequence, error) {
|
func (v *View) latestSequences(viewName string, instanceIDs ...string) ([]*repository.CurrentSequence, error) {
|
||||||
return repository.LatestSequences(v.Db, sequencesTable, viewName)
|
return repository.LatestSequences(v.Db, sequencesTable, viewName, instanceIDs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) updateSpoolerRunSequence(viewName string) error {
|
func (v *View) updateSpoolerRunSequence(viewName string) error {
|
||||||
|
@ -80,8 +80,8 @@ func (v *View) GetLatestTokenSequence(instanceID string) (*repository.CurrentSeq
|
|||||||
return v.latestSequence(tokenTable, instanceID)
|
return v.latestSequence(tokenTable, instanceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) GetLatestTokenSequences() ([]*repository.CurrentSequence, error) {
|
func (v *View) GetLatestTokenSequences(instanceIDs ...string) ([]*repository.CurrentSequence, error) {
|
||||||
return v.latestSequences(tokenTable)
|
return v.latestSequences(tokenTable, instanceIDs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) ProcessedTokenSequence(event *models.Event) error {
|
func (v *View) ProcessedTokenSequence(event *models.Event) error {
|
||||||
|
@ -143,8 +143,8 @@ func (v *View) GetLatestUserSequence(instanceID string) (*repository.CurrentSequ
|
|||||||
return v.latestSequence(userTable, instanceID)
|
return v.latestSequence(userTable, instanceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) GetLatestUserSequences() ([]*repository.CurrentSequence, error) {
|
func (v *View) GetLatestUserSequences(instanceIDs ...string) ([]*repository.CurrentSequence, error) {
|
||||||
return v.latestSequences(userTable)
|
return v.latestSequences(userTable, instanceIDs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) ProcessedUserSequence(event *models.Event) error {
|
func (v *View) ProcessedUserSequence(event *models.Event) error {
|
||||||
|
@ -60,8 +60,8 @@ func (v *View) GetLatestUserSessionSequence(instanceID string) (*repository.Curr
|
|||||||
return v.latestSequence(userSessionTable, instanceID)
|
return v.latestSequence(userSessionTable, instanceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) GetLatestUserSessionSequences() ([]*repository.CurrentSequence, error) {
|
func (v *View) GetLatestUserSessionSequences(instanceIDs ...string) ([]*repository.CurrentSequence, error) {
|
||||||
return v.latestSequences(userSessionTable)
|
return v.latestSequences(userSessionTable, instanceIDs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *View) ProcessedUserSessionSequence(event *models.Event) error {
|
func (v *View) ProcessedUserSessionSequence(event *models.Event) error {
|
||||||
|
@ -398,6 +398,41 @@ func (c *Commands) SetDefaultOrg(ctx context.Context, orgID string) (*domain.Obj
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Commands) ChangeSystemConfig(ctx context.Context, externalDomain string, externalPort uint16, externalSecure bool) error {
|
||||||
|
validations, err := c.prepareChangeSystemConfig(externalDomain, externalPort, externalSecure)(ctx, c.eventstore.Filter)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for instanceID, instanceValidations := range validations {
|
||||||
|
if len(instanceValidations.Validations) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ctx := authz.WithConsole(authz.WithInstanceID(ctx, instanceID), instanceValidations.ProjectID, instanceValidations.ConsoleAppID)
|
||||||
|
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, instanceValidations.Validations...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = c.eventstore.Push(ctx, cmds...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) prepareChangeSystemConfig(externalDomain string, externalPort uint16, externalSecure bool) func(ctx context.Context, filter preparation.FilterToQueryReducer) (map[string]*SystemConfigChangesValidation, error) {
|
||||||
|
return func(ctx context.Context, filter preparation.FilterToQueryReducer) (map[string]*SystemConfigChangesValidation, error) {
|
||||||
|
if externalDomain == "" || externalPort == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
writeModel, err := getSystemConfigWriteModel(ctx, filter, externalDomain, c.externalDomain, externalPort, c.externalPort, externalSecure, c.externalSecure)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return writeModel.NewChangedEvents(c), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func prepareAddInstance(a *instance.Aggregate, instanceName string, defaultLanguage language.Tag) preparation.Validation {
|
func prepareAddInstance(a *instance.Aggregate, instanceName string, defaultLanguage language.Tag) preparation.Validation {
|
||||||
return func() (preparation.CreateCommands, error) {
|
return func() (preparation.CreateCommands, error) {
|
||||||
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
||||||
@ -494,3 +529,17 @@ func getInstanceWriteModel(ctx context.Context, filter preparation.FilterToQuery
|
|||||||
err = writeModel.Reduce()
|
err = writeModel.Reduce()
|
||||||
return writeModel, err
|
return writeModel, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getSystemConfigWriteModel(ctx context.Context, filter preparation.FilterToQueryReducer, externalDomain, newExternalDomain string, externalPort, newExternalPort uint16, externalSecure, newExternalSecure bool) (*SystemConfigWriteModel, error) {
|
||||||
|
writeModel := NewSystemConfigWriteModel(externalDomain, newExternalDomain, externalPort, newExternalPort, externalSecure, newExternalSecure)
|
||||||
|
events, err := filter(ctx, writeModel.Query())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(events) == 0 {
|
||||||
|
return writeModel, nil
|
||||||
|
}
|
||||||
|
writeModel.AppendEvents(events...)
|
||||||
|
err = writeModel.Reduce()
|
||||||
|
return writeModel, err
|
||||||
|
}
|
||||||
|
@ -95,33 +95,68 @@ func (c *Commands) addInstanceDomain(a *instance.Aggregate, instanceDomain strin
|
|||||||
events := []eventstore.Command{
|
events := []eventstore.Command{
|
||||||
instance.NewDomainAddedEvent(ctx, &a.Aggregate, instanceDomain, generated),
|
instance.NewDomainAddedEvent(ctx, &a.Aggregate, instanceDomain, generated),
|
||||||
}
|
}
|
||||||
appWriteModel, err := getOIDCAppWriteModel(ctx, filter, authz.GetInstance(ctx).ProjectID(), authz.GetInstance(ctx).ConsoleApplicationID(), "")
|
consoleChangeEvent, err := c.updateConsoleRedirectURIs(ctx, filter, instanceDomain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if appWriteModel.State.Exists() {
|
return append(events, consoleChangeEvent), nil
|
||||||
redirectUrls := append(appWriteModel.RedirectUris, http.BuildHTTP(instanceDomain, c.externalPort, c.externalSecure)+consoleRedirectPath)
|
|
||||||
logoutUrls := append(appWriteModel.PostLogoutRedirectUris, http.BuildHTTP(instanceDomain, c.externalPort, c.externalSecure)+consolePostLogoutPath)
|
|
||||||
consoleChangeEvent, err := project.NewOIDCConfigChangedEvent(
|
|
||||||
ctx,
|
|
||||||
ProjectAggregateFromWriteModel(&appWriteModel.WriteModel),
|
|
||||||
appWriteModel.AppID,
|
|
||||||
[]project.OIDCConfigChanges{
|
|
||||||
project.ChangeRedirectURIs(redirectUrls),
|
|
||||||
project.ChangePostLogoutRedirectURIs(logoutUrls),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
events = append(events, consoleChangeEvent)
|
|
||||||
}
|
|
||||||
|
|
||||||
return events, nil
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Commands) prepareUpdateConsoleRedirectURIs(instanceDomain string) preparation.Validation {
|
||||||
|
return func() (preparation.CreateCommands, error) {
|
||||||
|
if instanceDomain = strings.TrimSpace(instanceDomain); instanceDomain == "" {
|
||||||
|
return nil, errors.ThrowInvalidArgument(nil, "INST-E3j3s", "Errors.Invalid.Argument")
|
||||||
|
}
|
||||||
|
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
||||||
|
consoleChangeEvent, err := c.updateConsoleRedirectURIs(ctx, filter, instanceDomain)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return []eventstore.Command{
|
||||||
|
consoleChangeEvent,
|
||||||
|
}, nil
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) updateConsoleRedirectURIs(ctx context.Context, filter preparation.FilterToQueryReducer, instanceDomain string) (*project.OIDCConfigChangedEvent, error) {
|
||||||
|
appWriteModel, err := getOIDCAppWriteModel(ctx, filter, authz.GetInstance(ctx).ProjectID(), authz.GetInstance(ctx).ConsoleApplicationID(), "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !appWriteModel.State.Exists() {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
redirectURI := http.BuildHTTP(instanceDomain, c.externalPort, c.externalSecure) + consoleRedirectPath
|
||||||
|
changes := make([]project.OIDCConfigChanges, 0, 2)
|
||||||
|
if !containsURI(appWriteModel.RedirectUris, redirectURI) {
|
||||||
|
changes = append(changes, project.ChangeRedirectURIs(append(appWriteModel.RedirectUris, redirectURI)))
|
||||||
|
}
|
||||||
|
postLogoutRedirectURI := http.BuildHTTP(instanceDomain, c.externalPort, c.externalSecure) + consolePostLogoutPath
|
||||||
|
if !containsURI(appWriteModel.PostLogoutRedirectUris, postLogoutRedirectURI) {
|
||||||
|
changes = append(changes, project.ChangePostLogoutRedirectURIs(append(appWriteModel.PostLogoutRedirectUris, postLogoutRedirectURI)))
|
||||||
|
}
|
||||||
|
return project.NewOIDCConfigChangedEvent(
|
||||||
|
ctx,
|
||||||
|
ProjectAggregateFromWriteModel(&appWriteModel.WriteModel),
|
||||||
|
appWriteModel.AppID,
|
||||||
|
changes,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
//checkUpdateConsoleRedirectURIs validates if the required console uri is present in the redirect_uris and post_logout_redirect_uris
|
||||||
|
//it will return true only if present in both list, otherwise false
|
||||||
|
func (c *Commands) checkUpdateConsoleRedirectURIs(instanceDomain string, redirectURIs, postLogoutRedirectURIs []string) bool {
|
||||||
|
redirectURI := http.BuildHTTP(instanceDomain, c.externalPort, c.externalSecure) + consoleRedirectPath
|
||||||
|
if !containsURI(redirectURIs, redirectURI) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
postLogoutRedirectURI := http.BuildHTTP(instanceDomain, c.externalPort, c.externalSecure) + consolePostLogoutPath
|
||||||
|
return containsURI(postLogoutRedirectURIs, postLogoutRedirectURI)
|
||||||
|
}
|
||||||
|
|
||||||
func setPrimaryInstanceDomain(a *instance.Aggregate, instanceDomain string) preparation.Validation {
|
func setPrimaryInstanceDomain(a *instance.Aggregate, instanceDomain string) preparation.Validation {
|
||||||
return func() (preparation.CreateCommands, error) {
|
return func() (preparation.CreateCommands, error) {
|
||||||
if instanceDomain = strings.TrimSpace(instanceDomain); instanceDomain == "" {
|
if instanceDomain = strings.TrimSpace(instanceDomain); instanceDomain == "" {
|
||||||
@ -174,3 +209,12 @@ func getInstanceDomainWriteModel(ctx context.Context, filter preparation.FilterT
|
|||||||
err = domainWriteModel.Reduce()
|
err = domainWriteModel.Reduce()
|
||||||
return domainWriteModel, err
|
return domainWriteModel, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func containsURI(uris []string, uri string) bool {
|
||||||
|
for _, u := range uris {
|
||||||
|
if u == uri {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -71,21 +71,28 @@ func (c *Commands) ChangeOrgDomainPolicy(ctx context.Context, resourceOwner stri
|
|||||||
return orgWriteModelToDomainPolicy(existingPolicy), nil
|
return orgWriteModelToDomainPolicy(existingPolicy), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) RemoveOrgDomainPolicy(ctx context.Context, orgID string) error {
|
func (c *Commands) RemoveOrgDomainPolicy(ctx context.Context, orgID string) (*domain.ObjectDetails, error) {
|
||||||
if orgID == "" {
|
if orgID == "" {
|
||||||
return caos_errs.ThrowInvalidArgument(nil, "Org-3H8fs", "Errors.ResourceOwnerMissing")
|
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-3H8fs", "Errors.ResourceOwnerMissing")
|
||||||
}
|
}
|
||||||
existingPolicy, err := c.orgDomainPolicyWriteModelByID(ctx, orgID)
|
existingPolicy, err := c.orgDomainPolicyWriteModelByID(ctx, orgID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
|
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
|
||||||
return caos_errs.ThrowNotFound(nil, "ORG-Dvsh3", "Errors.Org.DomainPolicy.NotFound")
|
return nil, caos_errs.ThrowNotFound(nil, "ORG-Dvsh3", "Errors.Org.DomainPolicy.NotFound")
|
||||||
}
|
}
|
||||||
|
|
||||||
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PolicyDomainWriteModel.WriteModel)
|
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PolicyDomainWriteModel.WriteModel)
|
||||||
_, err = c.eventstore.Push(ctx, org.NewDomainPolicyRemovedEvent(ctx, orgAgg))
|
pushedEvents, err := c.eventstore.Push(ctx, org.NewDomainPolicyRemovedEvent(ctx, orgAgg))
|
||||||
return err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = AppendAndReduce(existingPolicy, pushedEvents...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return writeModelToObjectDetails(&existingPolicy.PolicyDomainWriteModel.WriteModel), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) getOrgDomainPolicy(ctx context.Context, orgID string) (*domain.DomainPolicy, error) {
|
func (c *Commands) getOrgDomainPolicy(ctx context.Context, orgID string) (*domain.DomainPolicy, error) {
|
||||||
|
@ -384,13 +384,16 @@ func TestCommandSide_RemoveDomainPolicy(t *testing.T) {
|
|||||||
r := &Commands{
|
r := &Commands{
|
||||||
eventstore: tt.fields.eventstore,
|
eventstore: tt.fields.eventstore,
|
||||||
}
|
}
|
||||||
err := r.RemoveOrgDomainPolicy(tt.args.ctx, tt.args.orgID)
|
got, err := r.RemoveOrgDomainPolicy(tt.args.ctx, tt.args.orgID)
|
||||||
if tt.res.err == nil {
|
if tt.res.err == nil {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
if tt.res.err != nil && !tt.res.err(err) {
|
if tt.res.err != nil && !tt.res.err(err) {
|
||||||
t.Errorf("got wrong err: %v ", err)
|
t.Errorf("got wrong err: %v ", err)
|
||||||
}
|
}
|
||||||
|
if tt.res.err == nil {
|
||||||
|
assert.Equal(t, tt.res.want, got)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,8 @@ func (wm *PolicyDomainWriteModel) Reduce() error {
|
|||||||
if e.SMTPSenderAddressMatchesInstanceDomain != nil {
|
if e.SMTPSenderAddressMatchesInstanceDomain != nil {
|
||||||
wm.SMTPSenderAddressMatchesInstanceDomain = *e.SMTPSenderAddressMatchesInstanceDomain
|
wm.SMTPSenderAddressMatchesInstanceDomain = *e.SMTPSenderAddressMatchesInstanceDomain
|
||||||
}
|
}
|
||||||
|
case *policy.DomainPolicyRemovedEvent:
|
||||||
|
wm.State = domain.PolicyStateRemoved
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return wm.WriteModel.Reduce()
|
return wm.WriteModel.Reduce()
|
||||||
|
184
internal/command/system_model.go
Normal file
184
internal/command/system_model.go
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/command/preparation"
|
||||||
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
|
"github.com/zitadel/zitadel/internal/repository/project"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SystemConfigWriteModel struct {
|
||||||
|
eventstore.WriteModel
|
||||||
|
|
||||||
|
Instances map[string]*systemConfigChangesInstanceModel
|
||||||
|
externalDomain string
|
||||||
|
externalPort uint16
|
||||||
|
externalSecure bool
|
||||||
|
newExternalDomain string
|
||||||
|
newExternalPort uint16
|
||||||
|
newExternalSecure bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type systemConfigChangesInstanceModel struct {
|
||||||
|
Domains []string
|
||||||
|
GeneratedDomain string
|
||||||
|
ProjectID string
|
||||||
|
ConsoleAppID string
|
||||||
|
RedirectUris []string
|
||||||
|
PostLogoutRedirectUris []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSystemConfigWriteModel(externalDomain, newExternalDomain string, externalPort, newExternalPort uint16, externalSecure, newExternalSecure bool) *SystemConfigWriteModel {
|
||||||
|
return &SystemConfigWriteModel{
|
||||||
|
WriteModel: eventstore.WriteModel{},
|
||||||
|
Instances: make(map[string]*systemConfigChangesInstanceModel),
|
||||||
|
externalDomain: externalDomain,
|
||||||
|
externalPort: externalPort,
|
||||||
|
externalSecure: externalSecure,
|
||||||
|
newExternalDomain: newExternalDomain,
|
||||||
|
newExternalPort: newExternalPort,
|
||||||
|
newExternalSecure: newExternalSecure,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *SystemConfigWriteModel) Reduce() error {
|
||||||
|
for _, event := range wm.Events {
|
||||||
|
switch e := event.(type) {
|
||||||
|
case *instance.InstanceAddedEvent:
|
||||||
|
wm.Instances[e.Aggregate().InstanceID] = &systemConfigChangesInstanceModel{}
|
||||||
|
case *instance.InstanceRemovedEvent:
|
||||||
|
delete(wm.Instances, e.Aggregate().InstanceID)
|
||||||
|
case *instance.DomainAddedEvent:
|
||||||
|
if !e.Generated && e.Domain != wm.externalDomain && e.Domain != wm.newExternalDomain {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if e.Generated && !strings.HasSuffix(e.Domain, wm.externalDomain) && !strings.HasSuffix(e.Domain, wm.newExternalDomain) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
wm.Instances[e.Aggregate().InstanceID].Domains = append(wm.Instances[e.Aggregate().InstanceID].Domains, e.Domain)
|
||||||
|
case *instance.DomainRemovedEvent:
|
||||||
|
domains := wm.Instances[e.Aggregate().InstanceID].Domains
|
||||||
|
for i, domain := range domains {
|
||||||
|
if domain == e.Domain {
|
||||||
|
domains[i] = domains[len(domains)-1]
|
||||||
|
domains[len(domains)-1] = ""
|
||||||
|
wm.Instances[e.Aggregate().InstanceID].Domains = domains[:len(domains)-1]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case *instance.ProjectSetEvent:
|
||||||
|
wm.Instances[e.Aggregate().InstanceID].ProjectID = e.ProjectID
|
||||||
|
case *instance.ConsoleSetEvent:
|
||||||
|
wm.Instances[e.Aggregate().InstanceID].ConsoleAppID = e.AppID
|
||||||
|
case *project.OIDCConfigAddedEvent:
|
||||||
|
if wm.Instances[e.Aggregate().InstanceID].ConsoleAppID != e.AppID {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
wm.Instances[e.Aggregate().InstanceID].RedirectUris = e.RedirectUris
|
||||||
|
wm.Instances[e.Aggregate().InstanceID].PostLogoutRedirectUris = e.PostLogoutRedirectUris
|
||||||
|
case *project.OIDCConfigChangedEvent:
|
||||||
|
if wm.Instances[e.Aggregate().InstanceID].ConsoleAppID != e.AppID {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if e.RedirectUris != nil {
|
||||||
|
wm.Instances[e.Aggregate().InstanceID].RedirectUris = *e.RedirectUris
|
||||||
|
}
|
||||||
|
if e.PostLogoutRedirectUris != nil {
|
||||||
|
wm.Instances[e.Aggregate().InstanceID].PostLogoutRedirectUris = *e.PostLogoutRedirectUris
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *SystemConfigWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||||
|
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||||
|
AddQuery().
|
||||||
|
AggregateTypes(instance.AggregateType).
|
||||||
|
EventTypes(
|
||||||
|
instance.InstanceAddedEventType,
|
||||||
|
instance.InstanceRemovedEventType,
|
||||||
|
instance.InstanceDomainAddedEventType,
|
||||||
|
instance.InstanceDomainRemovedEventType,
|
||||||
|
instance.ProjectSetEventType,
|
||||||
|
instance.ConsoleSetEventType,
|
||||||
|
).
|
||||||
|
Or().
|
||||||
|
AggregateTypes(project.AggregateType).
|
||||||
|
EventTypes(
|
||||||
|
project.OIDCConfigAddedType,
|
||||||
|
project.OIDCConfigChangedType,
|
||||||
|
).
|
||||||
|
Builder()
|
||||||
|
}
|
||||||
|
|
||||||
|
type SystemConfigChangesValidation struct {
|
||||||
|
ProjectID string
|
||||||
|
ConsoleAppID string
|
||||||
|
Validations []preparation.Validation
|
||||||
|
InstanceID string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *SystemConfigWriteModel) NewChangedEvents(commands *Commands) map[string]*SystemConfigChangesValidation {
|
||||||
|
var newCustomDomainExists, isInstanceOfCustomDomain bool
|
||||||
|
var instanceOfCustomDomain string
|
||||||
|
cmds := make(map[string]*SystemConfigChangesValidation)
|
||||||
|
for i, inst := range wm.Instances {
|
||||||
|
cmds[i] = &SystemConfigChangesValidation{
|
||||||
|
InstanceID: i,
|
||||||
|
ProjectID: inst.ProjectID,
|
||||||
|
ConsoleAppID: inst.ConsoleAppID,
|
||||||
|
}
|
||||||
|
//check each instance separately for changes (using the generated domain) and check if there's an existing custom domain
|
||||||
|
newCustomDomainExists, isInstanceOfCustomDomain = wm.changeConfig(cmds[i], inst, commands)
|
||||||
|
if isInstanceOfCustomDomain || newCustomDomainExists {
|
||||||
|
instanceOfCustomDomain = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//handle the custom domain at last
|
||||||
|
if newCustomDomainExists {
|
||||||
|
//if the domain itself already exists, then only check if the uris of the console app exist as well
|
||||||
|
wm.changeURIs(cmds[instanceOfCustomDomain], wm.Instances[instanceOfCustomDomain], commands, wm.newExternalDomain)
|
||||||
|
return cmds
|
||||||
|
}
|
||||||
|
//otherwise the add instance domain will take care of the uris
|
||||||
|
cmds[instanceOfCustomDomain].Validations = append(cmds[instanceOfCustomDomain].Validations, commands.addInstanceDomain(instance.NewAggregate(instanceOfCustomDomain), wm.newExternalDomain, false))
|
||||||
|
return cmds
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *SystemConfigWriteModel) changeConfig(validation *SystemConfigChangesValidation, inst *systemConfigChangesInstanceModel, commands *Commands) (newCustomDomainExists, isInstanceOfCustomDomain bool) {
|
||||||
|
var newGeneratedDomain string
|
||||||
|
var newGeneratedDomainExists bool
|
||||||
|
for _, domain := range inst.Domains {
|
||||||
|
if domain == wm.newExternalDomain {
|
||||||
|
newCustomDomainExists = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if domain != wm.newExternalDomain && strings.HasSuffix(domain, wm.newExternalDomain) {
|
||||||
|
newGeneratedDomainExists = true
|
||||||
|
}
|
||||||
|
if !newCustomDomainExists && domain == wm.externalDomain {
|
||||||
|
isInstanceOfCustomDomain = true
|
||||||
|
}
|
||||||
|
if domain != wm.externalDomain && strings.HasSuffix(domain, wm.externalDomain) {
|
||||||
|
newGeneratedDomain = strings.TrimSuffix(domain, wm.externalDomain) + wm.newExternalDomain
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if newGeneratedDomainExists {
|
||||||
|
//if the domain itself already exists, then only check if the uris of the console app exist as well
|
||||||
|
wm.changeURIs(validation, inst, commands, newGeneratedDomain)
|
||||||
|
return newCustomDomainExists, isInstanceOfCustomDomain
|
||||||
|
}
|
||||||
|
//otherwise the add instance domain will take care of the uris
|
||||||
|
validation.Validations = append(validation.Validations, commands.addInstanceDomain(instance.NewAggregate(validation.InstanceID), newGeneratedDomain, true))
|
||||||
|
return newCustomDomainExists, isInstanceOfCustomDomain
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *SystemConfigWriteModel) changeURIs(validation *SystemConfigChangesValidation, inst *systemConfigChangesInstanceModel, commands *Commands, domain string) {
|
||||||
|
if commands.checkUpdateConsoleRedirectURIs(domain, inst.RedirectUris, inst.PostLogoutRedirectUris) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
validation.Validations = append(validation.Validations, commands.prepareUpdateConsoleRedirectURIs(domain))
|
||||||
|
}
|
@ -104,9 +104,10 @@ Machine:
|
|||||||
# JPath: "$.compute.vmId"
|
# JPath: "$.compute.vmId"
|
||||||
|
|
||||||
Projections:
|
Projections:
|
||||||
RequeueEvery: 10s
|
RequeueEvery: 60s
|
||||||
RetryFailedAfter: 1s
|
RetryFailedAfter: 1s
|
||||||
MaxFailureCount: 5
|
MaxFailureCount: 5
|
||||||
|
ConcurrentInstances: 10
|
||||||
BulkLimit: 200
|
BulkLimit: 200
|
||||||
MaxIterators: 1
|
MaxIterators: 1
|
||||||
Customizations:
|
Customizations:
|
||||||
@ -117,6 +118,7 @@ Auth:
|
|||||||
SearchLimit: 1000
|
SearchLimit: 1000
|
||||||
Spooler:
|
Spooler:
|
||||||
ConcurrentWorkers: 1
|
ConcurrentWorkers: 1
|
||||||
|
ConcurrentInstances: 10
|
||||||
BulkLimit: 10000
|
BulkLimit: 10000
|
||||||
FailureCountUntilSkip: 5
|
FailureCountUntilSkip: 5
|
||||||
|
|
||||||
@ -124,6 +126,7 @@ Admin:
|
|||||||
SearchLimit: 1000
|
SearchLimit: 1000
|
||||||
Spooler:
|
Spooler:
|
||||||
ConcurrentWorkers: 1
|
ConcurrentWorkers: 1
|
||||||
|
ConcurrentInstances: 10
|
||||||
BulkLimit: 10000
|
BulkLimit: 10000
|
||||||
FailureCountUntilSkip: 5
|
FailureCountUntilSkip: 5
|
||||||
|
|
||||||
@ -180,6 +183,7 @@ Notification:
|
|||||||
Repository:
|
Repository:
|
||||||
Spooler:
|
Spooler:
|
||||||
ConcurrentWorkers: 1
|
ConcurrentWorkers: 1
|
||||||
|
ConcurrentInstances: 10
|
||||||
BulkLimit: 10000
|
BulkLimit: 10000
|
||||||
FailureCountUntilSkip: 5
|
FailureCountUntilSkip: 5
|
||||||
Handlers:
|
Handlers:
|
||||||
|
@ -186,6 +186,15 @@ func (es *Eventstore) LatestSequence(ctx context.Context, queryFactory *SearchQu
|
|||||||
return es.repo.LatestSequence(ctx, query)
|
return es.repo.LatestSequence(ctx, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//InstanceIDs returns the instance ids found by the search query
|
||||||
|
func (es *Eventstore) InstanceIDs(ctx context.Context, queryFactory *SearchQueryBuilder) ([]string, error) {
|
||||||
|
query, err := queryFactory.build(authz.GetInstance(ctx).InstanceID())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return es.repo.InstanceIDs(ctx, query)
|
||||||
|
}
|
||||||
|
|
||||||
type QueryReducer interface {
|
type QueryReducer interface {
|
||||||
reducer
|
reducer
|
||||||
//Query returns the SearchQueryFactory for the events needed in reducer
|
//Query returns the SearchQueryFactory for the events needed in reducer
|
||||||
|
@ -688,10 +688,11 @@ func TestEventstore_aggregatesToEvents(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type testRepo struct {
|
type testRepo struct {
|
||||||
events []*repository.Event
|
events []*repository.Event
|
||||||
sequence uint64
|
sequence uint64
|
||||||
err error
|
instances []string
|
||||||
t *testing.T
|
err error
|
||||||
|
t *testing.T
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *testRepo) Health(ctx context.Context) error {
|
func (repo *testRepo) Health(ctx context.Context) error {
|
||||||
@ -735,6 +736,13 @@ func (repo *testRepo) LatestSequence(ctx context.Context, queryFactory *reposito
|
|||||||
return repo.sequence, nil
|
return repo.sequence, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repo *testRepo) InstanceIDs(ctx context.Context, queryFactory *repository.SearchQuery) ([]string, error) {
|
||||||
|
if repo.err != nil {
|
||||||
|
return nil, repo.err
|
||||||
|
}
|
||||||
|
return repo.instances, nil
|
||||||
|
}
|
||||||
|
|
||||||
func TestEventstore_Push(t *testing.T) {
|
func TestEventstore_Push(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
events []Command
|
events []Command
|
||||||
|
@ -6,12 +6,14 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/lib/pq"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/errors"
|
"github.com/zitadel/zitadel/internal/errors"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
currentSequenceStmtFormat = `SELECT current_sequence, aggregate_type, instance_id FROM %s WHERE projection_name = $1 FOR UPDATE`
|
currentSequenceStmtFormat = `SELECT current_sequence, aggregate_type, instance_id FROM %s WHERE projection_name = $1 AND instance_id = ANY ($2) FOR UPDATE`
|
||||||
updateCurrentSequencesStmtFormat = `UPSERT INTO %s (projection_name, aggregate_type, current_sequence, instance_id, timestamp) VALUES `
|
updateCurrentSequencesStmtFormat = `UPSERT INTO %s (projection_name, aggregate_type, current_sequence, instance_id, timestamp) VALUES `
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -22,8 +24,8 @@ type instanceSequence struct {
|
|||||||
sequence uint64
|
sequence uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *StatementHandler) currentSequences(ctx context.Context, query func(context.Context, string, ...interface{}) (*sql.Rows, error)) (currentSequences, error) {
|
func (h *StatementHandler) currentSequences(ctx context.Context, query func(context.Context, string, ...interface{}) (*sql.Rows, error), instanceIDs []string) (currentSequences, error) {
|
||||||
rows, err := query(ctx, h.currentSequenceStmt, h.ProjectionName)
|
rows, err := query(ctx, h.currentSequenceStmt, h.ProjectionName, pq.StringArray(instanceIDs))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/DATA-DOG/go-sqlmock"
|
"github.com/DATA-DOG/go-sqlmock"
|
||||||
|
"github.com/lib/pq"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
)
|
)
|
||||||
@ -123,34 +124,40 @@ func expectSavePointRelease() func(sqlmock.Sqlmock) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func expectCurrentSequence(tableName, projection string, seq uint64, aggregateType, instanceID string) func(sqlmock.Sqlmock) {
|
func expectCurrentSequence(tableName, projection string, seq uint64, aggregateType string, instanceIDs []string) func(sqlmock.Sqlmock) {
|
||||||
|
rows := sqlmock.NewRows([]string{"current_sequence", "aggregate_type", "instance_id"})
|
||||||
|
for _, instanceID := range instanceIDs {
|
||||||
|
rows.AddRow(seq, aggregateType, instanceID)
|
||||||
|
}
|
||||||
return func(m sqlmock.Sqlmock) {
|
return func(m sqlmock.Sqlmock) {
|
||||||
m.ExpectQuery(`SELECT current_sequence, aggregate_type, instance_id FROM ` + tableName + ` WHERE projection_name = \$1 FOR UPDATE`).
|
m.ExpectQuery(`SELECT current_sequence, aggregate_type, instance_id FROM `+tableName+` WHERE projection_name = \$1 AND instance_id = ANY \(\$2\) FOR UPDATE`).
|
||||||
WithArgs(
|
WithArgs(
|
||||||
projection,
|
projection,
|
||||||
|
pq.StringArray(instanceIDs),
|
||||||
).
|
).
|
||||||
WillReturnRows(
|
WillReturnRows(
|
||||||
sqlmock.NewRows([]string{"current_sequence", "aggregate_type", "instance_id"}).
|
rows,
|
||||||
AddRow(seq, aggregateType, instanceID),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func expectCurrentSequenceErr(tableName, projection string, err error) func(sqlmock.Sqlmock) {
|
func expectCurrentSequenceErr(tableName, projection string, instanceIDs []string, err error) func(sqlmock.Sqlmock) {
|
||||||
return func(m sqlmock.Sqlmock) {
|
return func(m sqlmock.Sqlmock) {
|
||||||
m.ExpectQuery(`SELECT current_sequence, aggregate_type, instance_id FROM ` + tableName + ` WHERE projection_name = \$1 FOR UPDATE`).
|
m.ExpectQuery(`SELECT current_sequence, aggregate_type, instance_id FROM `+tableName+` WHERE projection_name = \$1 AND instance_id = ANY \(\$2\) FOR UPDATE`).
|
||||||
WithArgs(
|
WithArgs(
|
||||||
projection,
|
projection,
|
||||||
|
pq.StringArray(instanceIDs),
|
||||||
).
|
).
|
||||||
WillReturnError(err)
|
WillReturnError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func expectCurrentSequenceNoRows(tableName, projection string) func(sqlmock.Sqlmock) {
|
func expectCurrentSequenceNoRows(tableName, projection string, instanceIDs []string) func(sqlmock.Sqlmock) {
|
||||||
return func(m sqlmock.Sqlmock) {
|
return func(m sqlmock.Sqlmock) {
|
||||||
m.ExpectQuery(`SELECT current_sequence, aggregate_type, instance_id FROM ` + tableName + ` WHERE projection_name = \$1 FOR UPDATE`).
|
m.ExpectQuery(`SELECT current_sequence, aggregate_type, instance_id FROM `+tableName+` WHERE projection_name = \$1 AND instance_id = ANY \(\$2\) FOR UPDATE`).
|
||||||
WithArgs(
|
WithArgs(
|
||||||
projection,
|
projection,
|
||||||
|
pq.StringArray(instanceIDs),
|
||||||
).
|
).
|
||||||
WillReturnRows(
|
WillReturnRows(
|
||||||
sqlmock.NewRows([]string{"current_sequence", "aggregate_type", "instance_id"}),
|
sqlmock.NewRows([]string{"current_sequence", "aggregate_type", "instance_id"}),
|
||||||
@ -158,11 +165,12 @@ func expectCurrentSequenceNoRows(tableName, projection string) func(sqlmock.Sqlm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func expectCurrentSequenceScanErr(tableName, projection string) func(sqlmock.Sqlmock) {
|
func expectCurrentSequenceScanErr(tableName, projection string, instanceIDs []string) func(sqlmock.Sqlmock) {
|
||||||
return func(m sqlmock.Sqlmock) {
|
return func(m sqlmock.Sqlmock) {
|
||||||
m.ExpectQuery(`SELECT current_sequence, aggregate_type, instance_id FROM ` + tableName + ` WHERE projection_name = \$1 FOR UPDATE`).
|
m.ExpectQuery(`SELECT current_sequence, aggregate_type, instance_id FROM `+tableName+` WHERE projection_name = \$1 AND instance_id = ANY \(\$2\) FOR UPDATE`).
|
||||||
WithArgs(
|
WithArgs(
|
||||||
projection,
|
projection,
|
||||||
|
pq.StringArray(instanceIDs),
|
||||||
).
|
).
|
||||||
WillReturnRows(
|
WillReturnRows(
|
||||||
sqlmock.NewRows([]string{"current_sequence", "aggregate_type", "instance_id"}).
|
sqlmock.NewRows([]string{"current_sequence", "aggregate_type", "instance_id"}).
|
||||||
@ -286,12 +294,34 @@ func expectLock(lockTable, workerName string, d time.Duration, instanceID string
|
|||||||
` \(locker_id, locked_until, projection_name, instance_id\) VALUES \(\$1, now\(\)\+\$2::INTERVAL, \$3\, \$4\)`+
|
` \(locker_id, locked_until, projection_name, instance_id\) VALUES \(\$1, now\(\)\+\$2::INTERVAL, \$3\, \$4\)`+
|
||||||
` ON CONFLICT \(projection_name, instance_id\)`+
|
` ON CONFLICT \(projection_name, instance_id\)`+
|
||||||
` DO UPDATE SET locker_id = \$1, locked_until = now\(\)\+\$2::INTERVAL`+
|
` DO UPDATE SET locker_id = \$1, locked_until = now\(\)\+\$2::INTERVAL`+
|
||||||
` WHERE `+lockTable+`\.projection_name = \$3 AND `+lockTable+`\.instance_id = \$4 AND \(`+lockTable+`\.locker_id = \$1 OR `+lockTable+`\.locked_until < now\(\)\)`).
|
` WHERE `+lockTable+`\.projection_name = \$3 AND `+lockTable+`\.instance_id = ANY \(\$5\) AND \(`+lockTable+`\.locker_id = \$1 OR `+lockTable+`\.locked_until < now\(\)\)`).
|
||||||
WithArgs(
|
WithArgs(
|
||||||
workerName,
|
workerName,
|
||||||
float64(d),
|
float64(d),
|
||||||
projectionName,
|
projectionName,
|
||||||
instanceID,
|
instanceID,
|
||||||
|
pq.StringArray{instanceID},
|
||||||
|
).
|
||||||
|
WillReturnResult(
|
||||||
|
sqlmock.NewResult(1, 1),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func expectLockMultipleInstances(lockTable, workerName string, d time.Duration, instanceID1, instanceID2 string) func(sqlmock.Sqlmock) {
|
||||||
|
return func(m sqlmock.Sqlmock) {
|
||||||
|
m.ExpectExec(`INSERT INTO `+lockTable+
|
||||||
|
` \(locker_id, locked_until, projection_name, instance_id\) VALUES \(\$1, now\(\)\+\$2::INTERVAL, \$3\, \$4\), \(\$1, now\(\)\+\$2::INTERVAL, \$3\, \$5\)`+
|
||||||
|
` ON CONFLICT \(projection_name, instance_id\)`+
|
||||||
|
` DO UPDATE SET locker_id = \$1, locked_until = now\(\)\+\$2::INTERVAL`+
|
||||||
|
` WHERE `+lockTable+`\.projection_name = \$3 AND `+lockTable+`\.instance_id = ANY \(\$6\) AND \(`+lockTable+`\.locker_id = \$1 OR `+lockTable+`\.locked_until < now\(\)\)`).
|
||||||
|
WithArgs(
|
||||||
|
workerName,
|
||||||
|
float64(d),
|
||||||
|
projectionName,
|
||||||
|
instanceID1,
|
||||||
|
instanceID2,
|
||||||
|
pq.StringArray{instanceID1, instanceID2},
|
||||||
).
|
).
|
||||||
WillReturnResult(
|
WillReturnResult(
|
||||||
sqlmock.NewResult(1, 1),
|
sqlmock.NewResult(1, 1),
|
||||||
@ -305,12 +335,13 @@ func expectLockNoRows(lockTable, workerName string, d time.Duration, instanceID
|
|||||||
` \(locker_id, locked_until, projection_name, instance_id\) VALUES \(\$1, now\(\)\+\$2::INTERVAL, \$3\, \$4\)`+
|
` \(locker_id, locked_until, projection_name, instance_id\) VALUES \(\$1, now\(\)\+\$2::INTERVAL, \$3\, \$4\)`+
|
||||||
` ON CONFLICT \(projection_name, instance_id\)`+
|
` ON CONFLICT \(projection_name, instance_id\)`+
|
||||||
` DO UPDATE SET locker_id = \$1, locked_until = now\(\)\+\$2::INTERVAL`+
|
` DO UPDATE SET locker_id = \$1, locked_until = now\(\)\+\$2::INTERVAL`+
|
||||||
` WHERE `+lockTable+`\.projection_name = \$3 AND `+lockTable+`\.instance_id = \$4 AND \(`+lockTable+`\.locker_id = \$1 OR `+lockTable+`\.locked_until < now\(\)\)`).
|
` WHERE `+lockTable+`\.projection_name = \$3 AND `+lockTable+`\.instance_id = ANY \(\$5\) AND \(`+lockTable+`\.locker_id = \$1 OR `+lockTable+`\.locked_until < now\(\)\)`).
|
||||||
WithArgs(
|
WithArgs(
|
||||||
workerName,
|
workerName,
|
||||||
float64(d),
|
float64(d),
|
||||||
projectionName,
|
projectionName,
|
||||||
instanceID,
|
instanceID,
|
||||||
|
pq.StringArray{instanceID},
|
||||||
).
|
).
|
||||||
WillReturnResult(driver.ResultNoRows)
|
WillReturnResult(driver.ResultNoRows)
|
||||||
}
|
}
|
||||||
@ -322,12 +353,13 @@ func expectLockErr(lockTable, workerName string, d time.Duration, instanceID str
|
|||||||
` \(locker_id, locked_until, projection_name, instance_id\) VALUES \(\$1, now\(\)\+\$2::INTERVAL, \$3\, \$4\)`+
|
` \(locker_id, locked_until, projection_name, instance_id\) VALUES \(\$1, now\(\)\+\$2::INTERVAL, \$3\, \$4\)`+
|
||||||
` ON CONFLICT \(projection_name, instance_id\)`+
|
` ON CONFLICT \(projection_name, instance_id\)`+
|
||||||
` DO UPDATE SET locker_id = \$1, locked_until = now\(\)\+\$2::INTERVAL`+
|
` DO UPDATE SET locker_id = \$1, locked_until = now\(\)\+\$2::INTERVAL`+
|
||||||
` WHERE `+lockTable+`\.projection_name = \$3 AND `+lockTable+`\.instance_id = \$4 AND \(`+lockTable+`\.locker_id = \$1 OR `+lockTable+`\.locked_until < now\(\)\)`).
|
` WHERE `+lockTable+`\.projection_name = \$3 AND `+lockTable+`\.instance_id = ANY \(\$5\) AND \(`+lockTable+`\.locker_id = \$1 OR `+lockTable+`\.locked_until < now\(\)\)`).
|
||||||
WithArgs(
|
WithArgs(
|
||||||
workerName,
|
workerName,
|
||||||
float64(d),
|
float64(d),
|
||||||
projectionName,
|
projectionName,
|
||||||
instanceID,
|
instanceID,
|
||||||
|
pq.StringArray{instanceID},
|
||||||
).
|
).
|
||||||
WillReturnError(err)
|
WillReturnError(err)
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/errors"
|
"github.com/zitadel/zitadel/internal/errors"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore/handler"
|
"github.com/zitadel/zitadel/internal/eventstore/handler"
|
||||||
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -75,84 +74,62 @@ func NewStatementHandler(
|
|||||||
bulkLimit: config.BulkLimit,
|
bulkLimit: config.BulkLimit,
|
||||||
Locker: NewLocker(config.Client, config.LockTable, config.ProjectionHandlerConfig.ProjectionName),
|
Locker: NewLocker(config.Client, config.LockTable, config.ProjectionHandlerConfig.ProjectionName),
|
||||||
}
|
}
|
||||||
h.ProjectionHandler = handler.NewProjectionHandler(config.ProjectionHandlerConfig, h.reduce, h.Update, h.SearchQuery)
|
h.ProjectionHandler = handler.NewProjectionHandler(ctx, config.ProjectionHandlerConfig, h.reduce, h.Update, h.SearchQuery, h.Lock, h.Unlock)
|
||||||
|
|
||||||
err := h.Init(ctx, config.InitCheck)
|
err := h.Init(ctx, config.InitCheck)
|
||||||
logging.OnError(err).Fatal("unable to initialize projections")
|
logging.OnError(err).Fatal("unable to initialize projections")
|
||||||
|
|
||||||
go h.Process(
|
|
||||||
ctx,
|
|
||||||
h.reduce,
|
|
||||||
h.Update,
|
|
||||||
h.Lock,
|
|
||||||
h.Unlock,
|
|
||||||
h.SearchQuery,
|
|
||||||
)
|
|
||||||
|
|
||||||
h.Subscribe(h.aggregates...)
|
h.Subscribe(h.aggregates...)
|
||||||
|
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *StatementHandler) TriggerBulk(ctx context.Context) {
|
func (h *StatementHandler) SearchQuery(ctx context.Context, instanceIDs []string) (*eventstore.SearchQueryBuilder, uint64, error) {
|
||||||
ctx, span := tracing.NewSpan(ctx)
|
sequences, err := h.currentSequences(ctx, h.client.QueryContext, instanceIDs)
|
||||||
var err error
|
|
||||||
defer span.EndWithError(err)
|
|
||||||
|
|
||||||
err = h.ProjectionHandler.TriggerBulk(ctx, h.Lock, h.Unlock)
|
|
||||||
logging.OnError(err).WithField("projection", h.ProjectionName).Warn("unable to trigger bulk")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *StatementHandler) SearchQuery(ctx context.Context) (*eventstore.SearchQueryBuilder, uint64, error) {
|
|
||||||
sequences, err := h.currentSequences(ctx, h.client.QueryContext)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
queryBuilder := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).Limit(h.bulkLimit)
|
queryBuilder := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).Limit(h.bulkLimit)
|
||||||
|
|
||||||
for _, aggregateType := range h.aggregates {
|
for _, aggregateType := range h.aggregates {
|
||||||
instances := make([]string, 0)
|
for _, instanceID := range instanceIDs {
|
||||||
for _, sequence := range sequences[aggregateType] {
|
var seq uint64
|
||||||
instances = appendToIgnoredInstances(instances, sequence.instanceID)
|
for _, sequence := range sequences[aggregateType] {
|
||||||
|
if sequence.instanceID == instanceID {
|
||||||
|
seq = sequence.sequence
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
queryBuilder.
|
queryBuilder.
|
||||||
AddQuery().
|
AddQuery().
|
||||||
AggregateTypes(aggregateType).
|
AggregateTypes(aggregateType).
|
||||||
SequenceGreater(sequence.sequence).
|
SequenceGreater(seq).
|
||||||
InstanceID(sequence.instanceID)
|
InstanceID(instanceID)
|
||||||
}
|
}
|
||||||
queryBuilder.
|
|
||||||
AddQuery().
|
|
||||||
AggregateTypes(aggregateType).
|
|
||||||
SequenceGreater(0).
|
|
||||||
ExcludedInstanceID(instances...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return queryBuilder, h.bulkLimit, nil
|
return queryBuilder, h.bulkLimit, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendToIgnoredInstances(instances []string, id string) []string {
|
|
||||||
for _, instance := range instances {
|
|
||||||
if instance == id {
|
|
||||||
return instances
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return append(instances, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
//Update implements handler.Update
|
//Update implements handler.Update
|
||||||
func (h *StatementHandler) Update(ctx context.Context, stmts []*handler.Statement, reduce handler.Reduce) (unexecutedStmts []*handler.Statement, err error) {
|
func (h *StatementHandler) Update(ctx context.Context, stmts []*handler.Statement, reduce handler.Reduce) (index int, err error) {
|
||||||
if len(stmts) == 0 {
|
if len(stmts) == 0 {
|
||||||
return nil, nil
|
return -1, nil
|
||||||
|
}
|
||||||
|
instanceIDs := make([]string, 0, len(stmts))
|
||||||
|
for _, stmt := range stmts {
|
||||||
|
instanceIDs = appendToInstanceIDs(instanceIDs, stmt.InstanceID)
|
||||||
}
|
}
|
||||||
tx, err := h.client.BeginTx(ctx, nil)
|
tx, err := h.client.BeginTx(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stmts, errors.ThrowInternal(err, "CRDB-e89Gq", "begin failed")
|
return -1, errors.ThrowInternal(err, "CRDB-e89Gq", "begin failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
sequences, err := h.currentSequences(ctx, tx.QueryContext)
|
sequences, err := h.currentSequences(ctx, tx.QueryContext, instanceIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return stmts, err
|
return -1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
//checks for events between create statement and current sequence
|
//checks for events between create statement and current sequence
|
||||||
@ -162,7 +139,7 @@ func (h *StatementHandler) Update(ctx context.Context, stmts []*handler.Statemen
|
|||||||
previousStmts, err := h.fetchPreviousStmts(ctx, tx, stmts[0].Sequence, stmts[0].InstanceID, sequences, reduce)
|
previousStmts, err := h.fetchPreviousStmts(ctx, tx, stmts[0].Sequence, stmts[0].InstanceID, sequences, reduce)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return stmts, err
|
return -1, err
|
||||||
}
|
}
|
||||||
stmts = append(previousStmts, stmts...)
|
stmts = append(previousStmts, stmts...)
|
||||||
}
|
}
|
||||||
@ -173,27 +150,19 @@ func (h *StatementHandler) Update(ctx context.Context, stmts []*handler.Statemen
|
|||||||
err = h.updateCurrentSequences(tx, sequences)
|
err = h.updateCurrentSequences(tx, sequences)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return stmts, err
|
return -1, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = tx.Commit(); err != nil {
|
if err = tx.Commit(); err != nil {
|
||||||
return stmts, err
|
return -1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if lastSuccessfulIdx == -1 && len(stmts) > 0 {
|
if lastSuccessfulIdx < len(stmts)-1 {
|
||||||
return stmts, handler.ErrSomeStmtsFailed
|
return lastSuccessfulIdx, handler.ErrSomeStmtsFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
unexecutedStmts = make([]*handler.Statement, len(stmts)-(lastSuccessfulIdx+1))
|
return lastSuccessfulIdx, nil
|
||||||
copy(unexecutedStmts, stmts[lastSuccessfulIdx+1:])
|
|
||||||
stmts = nil
|
|
||||||
|
|
||||||
if len(unexecutedStmts) > 0 {
|
|
||||||
return unexecutedStmts, handler.ErrSomeStmtsFailed
|
|
||||||
}
|
|
||||||
|
|
||||||
return unexecutedStmts, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *StatementHandler) fetchPreviousStmts(ctx context.Context, tx *sql.Tx, stmtSeq uint64, instanceID string, sequences currentSequences, reduce handler.Reduce) (previousStmts []*handler.Statement, err error) {
|
func (h *StatementHandler) fetchPreviousStmts(ctx context.Context, tx *sql.Tx, stmtSeq uint64, instanceID string, sequences currentSequences, reduce handler.Reduce) (previousStmts []*handler.Statement, err error) {
|
||||||
@ -316,3 +285,12 @@ func updateSequences(sequences currentSequences, stmt *handler.Statement) {
|
|||||||
sequence: stmt.Sequence,
|
sequence: stmt.Sequence,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func appendToInstanceIDs(instances []string, id string) []string {
|
||||||
|
for _, instance := range instances {
|
||||||
|
if instance == id {
|
||||||
|
return instances
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return append(instances, id)
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -61,9 +62,13 @@ func TestProjectionHandler_SearchQuery(t *testing.T) {
|
|||||||
aggregates []eventstore.AggregateType
|
aggregates []eventstore.AggregateType
|
||||||
bulkLimit uint64
|
bulkLimit uint64
|
||||||
}
|
}
|
||||||
|
type args struct {
|
||||||
|
instanceIDs []string
|
||||||
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
fields fields
|
fields fields
|
||||||
|
args args
|
||||||
want want
|
want want
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@ -74,13 +79,16 @@ func TestProjectionHandler_SearchQuery(t *testing.T) {
|
|||||||
aggregates: []eventstore.AggregateType{"testAgg"},
|
aggregates: []eventstore.AggregateType{"testAgg"},
|
||||||
bulkLimit: 5,
|
bulkLimit: 5,
|
||||||
},
|
},
|
||||||
|
args: args{
|
||||||
|
instanceIDs: []string{"instanceID1"},
|
||||||
|
},
|
||||||
want: want{
|
want: want{
|
||||||
limit: 0,
|
limit: 0,
|
||||||
isErr: func(err error) bool {
|
isErr: func(err error) bool {
|
||||||
return errors.Is(err, sql.ErrTxDone)
|
return errors.Is(err, sql.ErrTxDone)
|
||||||
},
|
},
|
||||||
expectations: []mockExpectation{
|
expectations: []mockExpectation{
|
||||||
expectCurrentSequenceErr("my_sequences", "my_projection", sql.ErrTxDone),
|
expectCurrentSequenceErr("my_sequences", "my_projection", []string{"instanceID1"}, sql.ErrTxDone),
|
||||||
},
|
},
|
||||||
SearchQueryBuilder: nil,
|
SearchQueryBuilder: nil,
|
||||||
},
|
},
|
||||||
@ -93,24 +101,56 @@ func TestProjectionHandler_SearchQuery(t *testing.T) {
|
|||||||
aggregates: []eventstore.AggregateType{"testAgg"},
|
aggregates: []eventstore.AggregateType{"testAgg"},
|
||||||
bulkLimit: 5,
|
bulkLimit: 5,
|
||||||
},
|
},
|
||||||
|
args: args{
|
||||||
|
instanceIDs: []string{"instanceID1"},
|
||||||
|
},
|
||||||
want: want{
|
want: want{
|
||||||
limit: 5,
|
limit: 5,
|
||||||
isErr: func(err error) bool {
|
isErr: func(err error) bool {
|
||||||
return err == nil
|
return err == nil
|
||||||
},
|
},
|
||||||
expectations: []mockExpectation{
|
expectations: []mockExpectation{
|
||||||
expectCurrentSequence("my_sequences", "my_projection", 5, "testAgg", "instanceID"),
|
expectCurrentSequence("my_sequences", "my_projection", 5, "testAgg", []string{"instanceID1"}),
|
||||||
},
|
},
|
||||||
SearchQueryBuilder: eventstore.
|
SearchQueryBuilder: eventstore.
|
||||||
NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||||
AddQuery().
|
AddQuery().
|
||||||
AggregateTypes("testAgg").
|
AggregateTypes("testAgg").
|
||||||
SequenceGreater(5).
|
SequenceGreater(5).
|
||||||
InstanceID("instanceID").
|
InstanceID("instanceID1").
|
||||||
|
Builder().
|
||||||
|
Limit(5),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple instances",
|
||||||
|
fields: fields{
|
||||||
|
sequenceTable: "my_sequences",
|
||||||
|
projectionName: "my_projection",
|
||||||
|
aggregates: []eventstore.AggregateType{"testAgg"},
|
||||||
|
bulkLimit: 5,
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
instanceIDs: []string{"instanceID1", "instanceID2"},
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
limit: 5,
|
||||||
|
isErr: func(err error) bool {
|
||||||
|
return err == nil
|
||||||
|
},
|
||||||
|
expectations: []mockExpectation{
|
||||||
|
expectCurrentSequence("my_sequences", "my_projection", 5, "testAgg", []string{"instanceID1", "instanceID2"}),
|
||||||
|
},
|
||||||
|
SearchQueryBuilder: eventstore.
|
||||||
|
NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||||
|
AddQuery().
|
||||||
|
AggregateTypes("testAgg").
|
||||||
|
SequenceGreater(5).
|
||||||
|
InstanceID("instanceID1").
|
||||||
Or().
|
Or().
|
||||||
AggregateTypes("testAgg").
|
AggregateTypes("testAgg").
|
||||||
SequenceGreater(0).
|
SequenceGreater(5).
|
||||||
ExcludedInstanceID("instanceID").
|
InstanceID("instanceID2").
|
||||||
Builder().
|
Builder().
|
||||||
Limit(5),
|
Limit(5),
|
||||||
},
|
},
|
||||||
@ -140,7 +180,7 @@ func TestProjectionHandler_SearchQuery(t *testing.T) {
|
|||||||
expectation(mock)
|
expectation(mock)
|
||||||
}
|
}
|
||||||
|
|
||||||
query, limit, err := h.SearchQuery(context.Background())
|
query, limit, err := h.SearchQuery(context.Background(), tt.args.instanceIDs)
|
||||||
if !tt.want.isErr(err) {
|
if !tt.want.isErr(err) {
|
||||||
t.Errorf("ProjectionHandler.prepareBulkStmts() error = %v", err)
|
t.Errorf("ProjectionHandler.prepareBulkStmts() error = %v", err)
|
||||||
return
|
return
|
||||||
@ -211,13 +251,14 @@ func TestStatementHandler_Update(t *testing.T) {
|
|||||||
aggregateType: "agg",
|
aggregateType: "agg",
|
||||||
sequence: 6,
|
sequence: 6,
|
||||||
previousSequence: 0,
|
previousSequence: 0,
|
||||||
|
instanceID: "instanceID",
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
want: want{
|
want: want{
|
||||||
expectations: []mockExpectation{
|
expectations: []mockExpectation{
|
||||||
expectBegin(),
|
expectBegin(),
|
||||||
expectCurrentSequenceErr("my_sequences", "my_projection", sql.ErrTxDone),
|
expectCurrentSequenceErr("my_sequences", "my_projection", []string{"instanceID"}, sql.ErrTxDone),
|
||||||
expectRollback(),
|
expectRollback(),
|
||||||
},
|
},
|
||||||
isErr: func(err error) bool {
|
isErr: func(err error) bool {
|
||||||
@ -241,13 +282,14 @@ func TestStatementHandler_Update(t *testing.T) {
|
|||||||
aggregateType: "agg",
|
aggregateType: "agg",
|
||||||
sequence: 6,
|
sequence: 6,
|
||||||
previousSequence: 0,
|
previousSequence: 0,
|
||||||
|
instanceID: "instanceID",
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
want: want{
|
want: want{
|
||||||
expectations: []mockExpectation{
|
expectations: []mockExpectation{
|
||||||
expectBegin(),
|
expectBegin(),
|
||||||
expectCurrentSequence("my_sequences", "my_projection", 5, "testAgg", "instanceID"),
|
expectCurrentSequence("my_sequences", "my_projection", 5, "testAgg", []string{"instanceID"}),
|
||||||
expectRollback(),
|
expectRollback(),
|
||||||
},
|
},
|
||||||
isErr: func(err error) bool {
|
isErr: func(err error) bool {
|
||||||
@ -272,6 +314,7 @@ func TestStatementHandler_Update(t *testing.T) {
|
|||||||
aggregateType: "testAgg",
|
aggregateType: "testAgg",
|
||||||
sequence: 7,
|
sequence: 7,
|
||||||
previousSequence: 6,
|
previousSequence: 6,
|
||||||
|
instanceID: "instanceID",
|
||||||
},
|
},
|
||||||
[]handler.Column{
|
[]handler.Column{
|
||||||
{
|
{
|
||||||
@ -284,7 +327,7 @@ func TestStatementHandler_Update(t *testing.T) {
|
|||||||
want: want{
|
want: want{
|
||||||
expectations: []mockExpectation{
|
expectations: []mockExpectation{
|
||||||
expectBegin(),
|
expectBegin(),
|
||||||
expectCurrentSequence("my_sequences", "my_projection", 5, "testAgg", "instanceID"),
|
expectCurrentSequence("my_sequences", "my_projection", 5, "testAgg", []string{"instanceID"}),
|
||||||
expectCommit(),
|
expectCommit(),
|
||||||
},
|
},
|
||||||
isErr: func(err error) bool {
|
isErr: func(err error) bool {
|
||||||
@ -322,7 +365,7 @@ func TestStatementHandler_Update(t *testing.T) {
|
|||||||
want: want{
|
want: want{
|
||||||
expectations: []mockExpectation{
|
expectations: []mockExpectation{
|
||||||
expectBegin(),
|
expectBegin(),
|
||||||
expectCurrentSequence("my_sequences", "my_projection", 5, "agg", "instanceID"),
|
expectCurrentSequence("my_sequences", "my_projection", 5, "agg", []string{"instanceID"}),
|
||||||
expectSavePoint(),
|
expectSavePoint(),
|
||||||
expectCreate("my_projection", []string{"col"}, []string{"$1"}),
|
expectCreate("my_projection", []string{"col"}, []string{"$1"}),
|
||||||
expectSavePointRelease(),
|
expectSavePointRelease(),
|
||||||
@ -364,7 +407,7 @@ func TestStatementHandler_Update(t *testing.T) {
|
|||||||
want: want{
|
want: want{
|
||||||
expectations: []mockExpectation{
|
expectations: []mockExpectation{
|
||||||
expectBegin(),
|
expectBegin(),
|
||||||
expectCurrentSequence("my_sequences", "my_projection", 5, "agg", "instanceID"),
|
expectCurrentSequence("my_sequences", "my_projection", 5, "agg", []string{"instanceID"}),
|
||||||
expectSavePoint(),
|
expectSavePoint(),
|
||||||
expectCreate("my_projection", []string{"col"}, []string{"$1"}),
|
expectCreate("my_projection", []string{"col"}, []string{"$1"}),
|
||||||
expectSavePointRelease(),
|
expectSavePointRelease(),
|
||||||
@ -399,7 +442,7 @@ func TestStatementHandler_Update(t *testing.T) {
|
|||||||
want: want{
|
want: want{
|
||||||
expectations: []mockExpectation{
|
expectations: []mockExpectation{
|
||||||
expectBegin(),
|
expectBegin(),
|
||||||
expectCurrentSequence("my_sequences", "my_projection", 5, "testAgg", "instanceID"),
|
expectCurrentSequence("my_sequences", "my_projection", 5, "testAgg", []string{"instanceID"}),
|
||||||
expectUpdateCurrentSequence("my_sequences", "my_projection", 7, "testAgg", "instanceID"),
|
expectUpdateCurrentSequence("my_sequences", "my_projection", 7, "testAgg", "instanceID"),
|
||||||
expectCommit(),
|
expectCommit(),
|
||||||
},
|
},
|
||||||
@ -431,7 +474,7 @@ func TestStatementHandler_Update(t *testing.T) {
|
|||||||
want: want{
|
want: want{
|
||||||
expectations: []mockExpectation{
|
expectations: []mockExpectation{
|
||||||
expectBegin(),
|
expectBegin(),
|
||||||
expectCurrentSequence("my_sequences", "my_projection", 5, "testAgg", "instanceID"),
|
expectCurrentSequence("my_sequences", "my_projection", 5, "testAgg", []string{"instanceID"}),
|
||||||
expectUpdateCurrentSequence("my_sequences", "my_projection", 7, "testAgg", "instanceID"),
|
expectUpdateCurrentSequence("my_sequences", "my_projection", 7, "testAgg", "instanceID"),
|
||||||
expectCommit(),
|
expectCommit(),
|
||||||
},
|
},
|
||||||
@ -470,13 +513,14 @@ func TestStatementHandler_Update(t *testing.T) {
|
|||||||
want: want{
|
want: want{
|
||||||
expectations: []mockExpectation{
|
expectations: []mockExpectation{
|
||||||
expectBegin(),
|
expectBegin(),
|
||||||
expectCurrentSequence("my_sequences", "my_projection", 5, "testAgg", "instanceID"),
|
expectCurrentSequence("my_sequences", "my_projection", 5, "testAgg", []string{"instanceID"}),
|
||||||
expectUpdateCurrentSequence("my_sequences", "my_projection", 7, "testAgg", "instanceID"),
|
expectUpdateCurrentSequence("my_sequences", "my_projection", 7, "testAgg", "instanceID"),
|
||||||
expectCommit(),
|
expectCommit(),
|
||||||
},
|
},
|
||||||
isErr: func(err error) bool {
|
isErr: func(err error) bool {
|
||||||
return errors.Is(err, nil)
|
return errors.Is(err, nil)
|
||||||
},
|
},
|
||||||
|
stmtsLen: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -488,17 +532,18 @@ func TestStatementHandler_Update(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer client.Close()
|
defer client.Close()
|
||||||
|
|
||||||
h := NewStatementHandler(context.Background(), StatementHandlerConfig{
|
h := &StatementHandler{
|
||||||
ProjectionHandlerConfig: handler.ProjectionHandlerConfig{
|
ProjectionHandler: &handler.ProjectionHandler{
|
||||||
ProjectionName: "my_projection",
|
Handler: handler.Handler{
|
||||||
HandlerConfig: handler.HandlerConfig{
|
|
||||||
Eventstore: tt.fields.eventstore,
|
Eventstore: tt.fields.eventstore,
|
||||||
},
|
},
|
||||||
RequeueEvery: 0,
|
ProjectionName: "my_projection",
|
||||||
},
|
},
|
||||||
SequenceTable: "my_sequences",
|
sequenceTable: "my_sequences",
|
||||||
Client: client,
|
currentSequenceStmt: fmt.Sprintf(currentSequenceStmtFormat, "my_sequences"),
|
||||||
})
|
updateSequencesBaseStmt: fmt.Sprintf(updateCurrentSequencesStmtFormat, "my_sequences"),
|
||||||
|
client: client,
|
||||||
|
}
|
||||||
|
|
||||||
h.aggregates = tt.fields.aggregates
|
h.aggregates = tt.fields.aggregates
|
||||||
|
|
||||||
@ -506,12 +551,12 @@ func TestStatementHandler_Update(t *testing.T) {
|
|||||||
expectation(mock)
|
expectation(mock)
|
||||||
}
|
}
|
||||||
|
|
||||||
stmts, err := h.Update(tt.args.ctx, tt.args.stmts, tt.args.reduce)
|
index, err := h.Update(tt.args.ctx, tt.args.stmts, tt.args.reduce)
|
||||||
if !tt.want.isErr(err) {
|
if !tt.want.isErr(err) {
|
||||||
t.Errorf("StatementHandler.Update() error = %v", err)
|
t.Errorf("StatementHandler.Update() error = %v", err)
|
||||||
}
|
}
|
||||||
if err == nil && tt.want.stmtsLen != len(stmts) {
|
if err == nil && tt.want.stmtsLen != index {
|
||||||
t.Errorf("wrong stmts length: want: %d got %d", tt.want.stmtsLen, len(stmts))
|
t.Errorf("wrong stmts length: want: %d got %d", tt.want.stmtsLen, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
mock.MatchExpectationsInOrder(true)
|
mock.MatchExpectationsInOrder(true)
|
||||||
@ -696,17 +741,12 @@ func TestProjectionHandler_fetchPreviousStmts(t *testing.T) {
|
|||||||
h := &StatementHandler{
|
h := &StatementHandler{
|
||||||
aggregates: tt.fields.aggregates,
|
aggregates: tt.fields.aggregates,
|
||||||
}
|
}
|
||||||
h.ProjectionHandler = handler.NewProjectionHandler(handler.ProjectionHandlerConfig{
|
h.ProjectionHandler = &handler.ProjectionHandler{
|
||||||
HandlerConfig: handler.HandlerConfig{
|
Handler: handler.Handler{
|
||||||
Eventstore: tt.fields.eventstore,
|
Eventstore: tt.fields.eventstore,
|
||||||
},
|
},
|
||||||
ProjectionName: "my_projection",
|
ProjectionName: "my_projection",
|
||||||
RequeueEvery: 0,
|
}
|
||||||
},
|
|
||||||
h.reduce,
|
|
||||||
h.Update,
|
|
||||||
h.SearchQuery,
|
|
||||||
)
|
|
||||||
stmts, err := h.fetchPreviousStmts(tt.args.ctx, nil, tt.args.stmtSeq, "", tt.args.sequences, tt.args.reduce)
|
stmts, err := h.fetchPreviousStmts(tt.args.ctx, nil, tt.args.stmtSeq, "", tt.args.sequences, tt.args.reduce)
|
||||||
if !tt.want.isErr(err) {
|
if !tt.want.isErr(err) {
|
||||||
t.Errorf("ProjectionHandler.prepareBulkStmts() error = %v", err)
|
t.Errorf("ProjectionHandler.prepareBulkStmts() error = %v", err)
|
||||||
@ -1311,7 +1351,8 @@ func TestStatementHandler_currentSequence(t *testing.T) {
|
|||||||
aggregates []eventstore.AggregateType
|
aggregates []eventstore.AggregateType
|
||||||
}
|
}
|
||||||
type args struct {
|
type args struct {
|
||||||
stmt handler.Statement
|
stmt handler.Statement
|
||||||
|
instanceIDs []string
|
||||||
}
|
}
|
||||||
type want struct {
|
type want struct {
|
||||||
expectations []mockExpectation
|
expectations []mockExpectation
|
||||||
@ -1338,7 +1379,7 @@ func TestStatementHandler_currentSequence(t *testing.T) {
|
|||||||
return errors.Is(err, sql.ErrConnDone)
|
return errors.Is(err, sql.ErrConnDone)
|
||||||
},
|
},
|
||||||
expectations: []mockExpectation{
|
expectations: []mockExpectation{
|
||||||
expectCurrentSequenceErr("my_table", "my_projection", sql.ErrConnDone),
|
expectCurrentSequenceErr("my_table", "my_projection", nil, sql.ErrConnDone),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1350,14 +1391,15 @@ func TestStatementHandler_currentSequence(t *testing.T) {
|
|||||||
aggregates: []eventstore.AggregateType{"agg"},
|
aggregates: []eventstore.AggregateType{"agg"},
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
stmt: handler.Statement{},
|
stmt: handler.Statement{},
|
||||||
|
instanceIDs: []string{"instanceID"},
|
||||||
},
|
},
|
||||||
want: want{
|
want: want{
|
||||||
isErr: func(err error) bool {
|
isErr: func(err error) bool {
|
||||||
return errors.Is(err, nil)
|
return errors.Is(err, nil)
|
||||||
},
|
},
|
||||||
expectations: []mockExpectation{
|
expectations: []mockExpectation{
|
||||||
expectCurrentSequenceNoRows("my_table", "my_projection"),
|
expectCurrentSequenceNoRows("my_table", "my_projection", []string{"instanceID"}),
|
||||||
},
|
},
|
||||||
sequences: currentSequences{},
|
sequences: currentSequences{},
|
||||||
},
|
},
|
||||||
@ -1370,14 +1412,15 @@ func TestStatementHandler_currentSequence(t *testing.T) {
|
|||||||
aggregates: []eventstore.AggregateType{"agg"},
|
aggregates: []eventstore.AggregateType{"agg"},
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
stmt: handler.Statement{},
|
stmt: handler.Statement{},
|
||||||
|
instanceIDs: []string{"instanceID"},
|
||||||
},
|
},
|
||||||
want: want{
|
want: want{
|
||||||
isErr: func(err error) bool {
|
isErr: func(err error) bool {
|
||||||
return errors.Is(err, sql.ErrTxDone)
|
return errors.Is(err, sql.ErrTxDone)
|
||||||
},
|
},
|
||||||
expectations: []mockExpectation{
|
expectations: []mockExpectation{
|
||||||
expectCurrentSequenceScanErr("my_table", "my_projection"),
|
expectCurrentSequenceScanErr("my_table", "my_projection", []string{"instanceID"}),
|
||||||
},
|
},
|
||||||
sequences: currentSequences{},
|
sequences: currentSequences{},
|
||||||
},
|
},
|
||||||
@ -1390,14 +1433,15 @@ func TestStatementHandler_currentSequence(t *testing.T) {
|
|||||||
aggregates: []eventstore.AggregateType{"agg"},
|
aggregates: []eventstore.AggregateType{"agg"},
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
stmt: handler.Statement{},
|
stmt: handler.Statement{},
|
||||||
|
instanceIDs: []string{"instanceID"},
|
||||||
},
|
},
|
||||||
want: want{
|
want: want{
|
||||||
isErr: func(err error) bool {
|
isErr: func(err error) bool {
|
||||||
return errors.Is(err, nil)
|
return errors.Is(err, nil)
|
||||||
},
|
},
|
||||||
expectations: []mockExpectation{
|
expectations: []mockExpectation{
|
||||||
expectCurrentSequence("my_table", "my_projection", 5, "agg", "instanceID"),
|
expectCurrentSequence("my_table", "my_projection", 5, "agg", []string{"instanceID"}),
|
||||||
},
|
},
|
||||||
sequences: currentSequences{
|
sequences: currentSequences{
|
||||||
"agg": []*instanceSequence{
|
"agg": []*instanceSequence{
|
||||||
@ -1409,15 +1453,48 @@ func TestStatementHandler_currentSequence(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "multiple found",
|
||||||
|
fields: fields{
|
||||||
|
sequenceTable: "my_table",
|
||||||
|
projectionName: "my_projection",
|
||||||
|
aggregates: []eventstore.AggregateType{"agg"},
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
stmt: handler.Statement{},
|
||||||
|
instanceIDs: []string{"instanceID1", "instanceID2"},
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
isErr: func(err error) bool {
|
||||||
|
return errors.Is(err, nil)
|
||||||
|
},
|
||||||
|
expectations: []mockExpectation{
|
||||||
|
expectCurrentSequence("my_table", "my_projection", 5, "agg", []string{"instanceID1", "instanceID2"}),
|
||||||
|
},
|
||||||
|
sequences: currentSequences{
|
||||||
|
"agg": []*instanceSequence{
|
||||||
|
{
|
||||||
|
sequence: 5,
|
||||||
|
instanceID: "instanceID1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sequence: 5,
|
||||||
|
instanceID: "instanceID2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
h := NewStatementHandler(context.Background(), StatementHandlerConfig{
|
h := &StatementHandler{
|
||||||
ProjectionHandlerConfig: handler.ProjectionHandlerConfig{
|
ProjectionHandler: &handler.ProjectionHandler{
|
||||||
ProjectionName: tt.fields.projectionName,
|
ProjectionName: tt.fields.projectionName,
|
||||||
},
|
},
|
||||||
SequenceTable: tt.fields.sequenceTable,
|
sequenceTable: tt.fields.sequenceTable,
|
||||||
})
|
currentSequenceStmt: fmt.Sprintf(currentSequenceStmtFormat, tt.fields.sequenceTable),
|
||||||
|
}
|
||||||
|
|
||||||
h.aggregates = tt.fields.aggregates
|
h.aggregates = tt.fields.aggregates
|
||||||
|
|
||||||
@ -1440,7 +1517,7 @@ func TestStatementHandler_currentSequence(t *testing.T) {
|
|||||||
t.Fatalf("unexpected err in begin: %v", err)
|
t.Fatalf("unexpected err in begin: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
seq, err := h.currentSequences(context.Background(), tx.QueryContext)
|
seq, err := h.currentSequences(context.Background(), tx.QueryContext, tt.args.instanceIDs)
|
||||||
if !tt.want.isErr(err) {
|
if !tt.want.isErr(err) {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -1615,12 +1692,13 @@ func TestStatementHandler_updateCurrentSequence(t *testing.T) {
|
|||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
|
||||||
h := NewStatementHandler(context.Background(), StatementHandlerConfig{
|
h := &StatementHandler{
|
||||||
ProjectionHandlerConfig: handler.ProjectionHandlerConfig{
|
ProjectionHandler: &handler.ProjectionHandler{
|
||||||
ProjectionName: tt.fields.projectionName,
|
ProjectionName: tt.fields.projectionName,
|
||||||
},
|
},
|
||||||
SequenceTable: tt.fields.sequenceTable,
|
sequenceTable: tt.fields.sequenceTable,
|
||||||
})
|
updateSequencesBaseStmt: fmt.Sprintf(updateCurrentSequencesStmtFormat, tt.fields.sequenceTable),
|
||||||
|
}
|
||||||
|
|
||||||
h.aggregates = tt.fields.aggregates
|
h.aggregates = tt.fields.aggregates
|
||||||
|
|
||||||
|
@ -4,8 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/lib/pq"
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/errors"
|
"github.com/zitadel/zitadel/internal/errors"
|
||||||
@ -14,20 +17,20 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
lockStmtFormat = "INSERT INTO %[1]s" +
|
lockStmtFormat = "INSERT INTO %[1]s" +
|
||||||
" (locker_id, locked_until, projection_name, instance_id) VALUES ($1, now()+$2::INTERVAL, $3, $4)" +
|
" (locker_id, locked_until, projection_name, instance_id) VALUES %[2]s" +
|
||||||
" ON CONFLICT (projection_name, instance_id)" +
|
" ON CONFLICT (projection_name, instance_id)" +
|
||||||
" DO UPDATE SET locker_id = $1, locked_until = now()+$2::INTERVAL" +
|
" DO UPDATE SET locker_id = $1, locked_until = now()+$2::INTERVAL" +
|
||||||
" WHERE %[1]s.projection_name = $3 AND %[1]s.instance_id = $4 AND (%[1]s.locker_id = $1 OR %[1]s.locked_until < now())"
|
" WHERE %[1]s.projection_name = $3 AND %[1]s.instance_id = ANY ($%[3]d) AND (%[1]s.locker_id = $1 OR %[1]s.locked_until < now())"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Locker interface {
|
type Locker interface {
|
||||||
Lock(ctx context.Context, lockDuration time.Duration, instanceID string) <-chan error
|
Lock(ctx context.Context, lockDuration time.Duration, instanceIDs ...string) <-chan error
|
||||||
Unlock(instanceID string) error
|
Unlock(instanceIDs ...string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type locker struct {
|
type locker struct {
|
||||||
client *sql.DB
|
client *sql.DB
|
||||||
lockStmt string
|
lockStmt func(values string, instances int) string
|
||||||
workerName string
|
workerName string
|
||||||
projectionName string
|
projectionName string
|
||||||
}
|
}
|
||||||
@ -36,25 +39,27 @@ func NewLocker(client *sql.DB, lockTable, projectionName string) Locker {
|
|||||||
workerName, err := id.SonyFlakeGenerator().Next()
|
workerName, err := id.SonyFlakeGenerator().Next()
|
||||||
logging.OnError(err).Panic("unable to generate lockID")
|
logging.OnError(err).Panic("unable to generate lockID")
|
||||||
return &locker{
|
return &locker{
|
||||||
client: client,
|
client: client,
|
||||||
lockStmt: fmt.Sprintf(lockStmtFormat, lockTable),
|
lockStmt: func(values string, instances int) string {
|
||||||
|
return fmt.Sprintf(lockStmtFormat, lockTable, values, instances)
|
||||||
|
},
|
||||||
workerName: workerName,
|
workerName: workerName,
|
||||||
projectionName: projectionName,
|
projectionName: projectionName,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *locker) Lock(ctx context.Context, lockDuration time.Duration, instanceID string) <-chan error {
|
func (h *locker) Lock(ctx context.Context, lockDuration time.Duration, instanceIDs ...string) <-chan error {
|
||||||
errs := make(chan error)
|
errs := make(chan error)
|
||||||
go h.handleLock(ctx, errs, lockDuration, instanceID)
|
go h.handleLock(ctx, errs, lockDuration, instanceIDs...)
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *locker) handleLock(ctx context.Context, errs chan error, lockDuration time.Duration, instanceID string) {
|
func (h *locker) handleLock(ctx context.Context, errs chan error, lockDuration time.Duration, instanceIDs ...string) {
|
||||||
renewLock := time.NewTimer(0)
|
renewLock := time.NewTimer(0)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-renewLock.C:
|
case <-renewLock.C:
|
||||||
errs <- h.renewLock(ctx, lockDuration, instanceID)
|
errs <- h.renewLock(ctx, lockDuration, instanceIDs...)
|
||||||
//refresh the lock 500ms before it times out. 500ms should be enough for one transaction
|
//refresh the lock 500ms before it times out. 500ms should be enough for one transaction
|
||||||
renewLock.Reset(lockDuration - (500 * time.Millisecond))
|
renewLock.Reset(lockDuration - (500 * time.Millisecond))
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
@ -65,24 +70,38 @@ func (h *locker) handleLock(ctx context.Context, errs chan error, lockDuration t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *locker) renewLock(ctx context.Context, lockDuration time.Duration, instanceID string) error {
|
func (h *locker) renewLock(ctx context.Context, lockDuration time.Duration, instanceIDs ...string) error {
|
||||||
//the unit of crdb interval is seconds (https://www.cockroachlabs.com/docs/stable/interval.html).
|
lockStmt, values := h.lockStatement(lockDuration, instanceIDs)
|
||||||
res, err := h.client.ExecContext(ctx, h.lockStmt, h.workerName, lockDuration.Seconds(), h.projectionName, instanceID)
|
res, err := h.client.ExecContext(ctx, lockStmt, values...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.ThrowInternal(err, "CRDB-uaDoR", "unable to execute lock")
|
return errors.ThrowInternal(err, "CRDB-uaDoR", "unable to execute lock")
|
||||||
}
|
}
|
||||||
|
|
||||||
if rows, _ := res.RowsAffected(); rows == 0 {
|
if rows, _ := res.RowsAffected(); rows == 0 {
|
||||||
return errors.ThrowAlreadyExists(nil, "CRDB-mmi4J", "projection already locked")
|
return errors.ThrowAlreadyExists(nil, "CRDB-mmi4J", "projection already locked")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *locker) Unlock(instanceID string) error {
|
func (h *locker) Unlock(instanceIDs ...string) error {
|
||||||
_, err := h.client.Exec(h.lockStmt, h.workerName, float64(0), h.projectionName, instanceID)
|
lockStmt, values := h.lockStatement(0, instanceIDs)
|
||||||
|
_, err := h.client.Exec(lockStmt, values...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.ThrowUnknown(err, "CRDB-JjfwO", "unlock failed")
|
return errors.ThrowUnknown(err, "CRDB-JjfwO", "unlock failed")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *locker) lockStatement(lockDuration time.Duration, instanceIDs []string) (string, []interface{}) {
|
||||||
|
valueQueries := make([]string, len(instanceIDs))
|
||||||
|
values := make([]interface{}, len(instanceIDs)+4)
|
||||||
|
values[0] = h.workerName
|
||||||
|
//the unit of crdb interval is seconds (https://www.cockroachlabs.com/docs/stable/interval.html).
|
||||||
|
values[1] = lockDuration.Seconds()
|
||||||
|
values[2] = h.projectionName
|
||||||
|
for i, instanceID := range instanceIDs {
|
||||||
|
valueQueries[i] = "($1, now()+$2::INTERVAL, $3, $" + strconv.Itoa(i+4) + ")"
|
||||||
|
values[i+3] = instanceID
|
||||||
|
}
|
||||||
|
values[len(values)-1] = pq.StringArray(instanceIDs)
|
||||||
|
return h.lockStmt(strings.Join(valueQueries, ", "), len(values)), values
|
||||||
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user