mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-12 02:54:20 +00:00
Merge branch 'master' into new-eventstore
This commit is contained in:
commit
5dd60f01e0
@ -47,7 +47,7 @@ SystemDefaults:
|
||||
MachineKeySize: 2048
|
||||
Multifactors:
|
||||
OTP:
|
||||
Issuer: 'Zitadel'
|
||||
Issuer: 'ZITADEL'
|
||||
VerificationKey:
|
||||
EncryptionKeyID: $ZITADEL_OTP_VERIFICATION_KEY
|
||||
VerificationLifetimes:
|
||||
@ -86,9 +86,9 @@ SystemDefaults:
|
||||
FromName: $EMAIL_SENDER_NAME
|
||||
Tls: $SMTP_TLS
|
||||
Twilio:
|
||||
SID: $TWILIO_SERVICE_SID
|
||||
SID: $TWILIO_SERVICE_SID
|
||||
Token: $TWILIO_TOKEN
|
||||
From: $TWILIO_SENDER_NAME
|
||||
From: $TWILIO_SENDER_NAME
|
||||
TemplateData:
|
||||
InitCode:
|
||||
Title: 'InitCode.Title'
|
||||
@ -127,5 +127,6 @@ SystemDefaults:
|
||||
ButtonText: 'DomainClaimed.ButtonText'
|
||||
WebAuthN:
|
||||
ID: $ZITADEL_COOKIE_DOMAIN
|
||||
Origin: $ZITADEL_ACCOUNTS
|
||||
OriginLogin: $ZITADEL_ACCOUNTS
|
||||
OriginConsole: $ZITADEL_CONSOLE
|
||||
DisplayName: ZITADEL
|
768
console/package-lock.json
generated
768
console/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -44,13 +44,13 @@
|
||||
"zone.js": "~0.11.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~0.1100.2",
|
||||
"@angular/cli": "~11.0.2",
|
||||
"@angular-devkit/build-angular": "~0.1100.3",
|
||||
"@angular/cli": "~11.0.3",
|
||||
"@angular/compiler-cli": "~11.0.0",
|
||||
"@types/jasmine": "~3.6.2",
|
||||
"@angular/language-service": "~11.0.2",
|
||||
"@angular/language-service": "~11.0.3",
|
||||
"@types/jasminewd2": "~2.0.3",
|
||||
"@types/node": "^14.14.9",
|
||||
"@types/node": "^14.14.10",
|
||||
"codelyzer": "^6.0.0",
|
||||
"jasmine-core": "~3.6.0",
|
||||
"jasmine-spec-reporter": "~6.0.0",
|
||||
@ -59,12 +59,12 @@
|
||||
"karma-coverage-istanbul-reporter": "~3.0.2",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "^1.5.0",
|
||||
"prettier": "^2.2.0",
|
||||
"prettier": "^2.2.1",
|
||||
"protractor": "~7.0.0",
|
||||
"stylelint": "^13.8.0",
|
||||
"stylelint-config-standard": "^20.0.0",
|
||||
"stylelint-scss": "^3.18.0",
|
||||
"ts-node": "~9.0.0",
|
||||
"ts-node": "~9.1.0",
|
||||
"tslint": "~6.1.3",
|
||||
"typescript": "^4.0.5"
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<app-detail-layout [backRouterLink]="[ serviceType === PolicyComponentServiceType.ADMIN ? '/iam' : '/org']"
|
||||
<app-detail-layout [backRouterLink]="[ serviceType === PolicyComponentServiceType.ADMIN ? '/iam/policies' : '/org']"
|
||||
[title]="'POLICY.LOGIN_POLICY.TITLE' | translate"
|
||||
[description]="(serviceType==PolicyComponentServiceType.MGMT ? 'POLICY.LOGIN_POLICY.DESCRIPTIONCREATEMGMT' : PolicyComponentServiceType.ADMIN ? 'POLICY.LOGIN_POLICY.DESCRIPTIONCREATEADMIN' : '') | translate">
|
||||
<p class="default" *ngIf="isDefault"> {{'POLICY.DEFAULTLABEL' | translate}}</p>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<app-detail-layout [backRouterLink]="[ serviceType === PolicyComponentServiceType.ADMIN ? '/iam' : '/org']"
|
||||
[title]="'POLICY.IAM_POLICY.TITLECREATE' | translate" [description]="'POLICY.IAM_POLICY.DESCRIPTION' | translate">
|
||||
<app-detail-layout [backRouterLink]="[ serviceType === PolicyComponentServiceType.ADMIN ? '/iam/policies' : '/org']"
|
||||
[title]="'POLICY.IAM_POLICY.TITLE' | translate" [description]="'POLICY.IAM_POLICY.DESCRIPTION' | translate">
|
||||
<p class="default" *ngIf="isDefault"> {{'POLICY.DEFAULTLABEL' | translate}}</p>
|
||||
|
||||
<ng-template appHasRole [appHasRole]="['iam.policy.delete']">
|
||||
|
@ -1,4 +1,4 @@
|
||||
<app-detail-layout [backRouterLink]="[ serviceType === PolicyComponentServiceType.ADMIN ? '/iam' : '/org']"
|
||||
<app-detail-layout [backRouterLink]="[ serviceType === PolicyComponentServiceType.ADMIN ? '/iam/policies' : '/org']"
|
||||
[title]="'POLICY.PWD_AGE.TITLE' | translate" [description]="'POLICY.PWD_AGE.DESCRIPTION' | translate">
|
||||
<ng-template appHasRole [appHasRole]="['policy.delete']">
|
||||
<button *ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault"
|
||||
|
@ -1,4 +1,4 @@
|
||||
<app-detail-layout [backRouterLink]="[ serviceType === PolicyComponentServiceType.ADMIN ? '/iam' : '/org']"
|
||||
<app-detail-layout [backRouterLink]="[ serviceType === PolicyComponentServiceType.ADMIN ? '/iam/policies' : '/org']"
|
||||
[title]="'POLICY.PWD_COMPLEXITY.TITLE' | translate" [description]="'POLICY.PWD_COMPLEXITY.DESCRIPTION' | translate">
|
||||
|
||||
<p class="default" *ngIf="isDefault"> {{'POLICY.DEFAULTLABEL' | translate}}</p>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<app-detail-layout [backRouterLink]="[ serviceType === PolicyComponentServiceType.ADMIN ? '/iam' : '/org']"
|
||||
<app-detail-layout [backRouterLink]="[ serviceType === PolicyComponentServiceType.ADMIN ? '/iam/policies' : '/org']"
|
||||
[title]="'POLICY.PWD_LOCKOUT.TITLE' | translate" [description]="'POLICY.PWD_LOCKOUT.DESCRIPTION' | translate">
|
||||
<p class="default" *ngIf="isDefault"> {{'POLICY.DEFAULTLABEL' | translate}}</p>
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
<div class="row-lyt">
|
||||
<ng-template appHasRole
|
||||
[appHasRole]="PolicyGridType.IAM ? ['iam.policy.read'] : PolicyGridType.ORG ? ['policy.read'] : []">
|
||||
[appHasRole]="type == PolicyGridType.IAM ? ['iam.policy.read'] : type == PolicyGridType.ORG ? ['policy.read'] : []">
|
||||
<div class="p-item card">
|
||||
<div class="avatar">
|
||||
<mat-icon class="icon" svgIcon="mdi_textbox_password"></mat-icon>
|
||||
@ -21,7 +21,8 @@
|
||||
|
||||
<span class="fill-space"></span>
|
||||
<div class="btn-wrapper">
|
||||
<button [routerLink]="[ 'policy', PolicyComponentType.COMPLEXITY ]"
|
||||
<button
|
||||
[routerLink]="[type == PolicyGridType.IAM ? '/iam' : type == PolicyGridType.ORG ? '/org' : '', 'policy', PolicyComponentType.COMPLEXITY ]"
|
||||
mat-stroked-button>{{'POLICY.BTN_EDIT' | translate}}</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -45,7 +46,8 @@
|
||||
<span class="fill-space"></span>
|
||||
<div class="btn-wrapper">
|
||||
<ng-template appHasRole [appHasRole]="['iam.policy.write']">
|
||||
<button [routerLink]="[ 'policy', PolicyComponentType.IAM ]"
|
||||
<button
|
||||
[routerLink]="[type == PolicyGridType.IAM ? '/iam' : type == PolicyGridType.ORG ? '/org' : '','policy', PolicyComponentType.IAM ]"
|
||||
mat-stroked-button>{{'POLICY.BTN_EDIT' | translate}}</button>
|
||||
</ng-template>
|
||||
</div>
|
||||
@ -53,7 +55,7 @@
|
||||
</ng-template>
|
||||
|
||||
<ng-template appHasRole
|
||||
[appHasRole]="PolicyGridType.IAM ? ['iam.policy.read'] : PolicyGridType.ORG ? ['policy.read'] : []">
|
||||
[appHasRole]="type == PolicyGridType.IAM ? ['iam.policy.read'] : type == PolicyGridType.ORG ? ['policy.read'] : []">
|
||||
<div class="p-item card">
|
||||
<div class="avatar">
|
||||
<i class="icon las la-sign-in-alt"></i>
|
||||
@ -73,7 +75,8 @@
|
||||
<span class="fill-space"></span>
|
||||
<div class="btn-wrapper">
|
||||
<ng-template appHasRole [appHasRole]="['policy.write']">
|
||||
<button [routerLink]="[ 'policy', PolicyComponentType.LOGIN ]"
|
||||
<button
|
||||
[routerLink]="[type == PolicyGridType.IAM ? '/iam' : type == PolicyGridType.ORG ? '/org' : '','policy', PolicyComponentType.LOGIN ]"
|
||||
mat-stroked-button>{{'POLICY.BTN_EDIT' | translate}}</button>
|
||||
</ng-template>
|
||||
</div>
|
||||
@ -99,7 +102,8 @@
|
||||
<span class="fill-space"></span>
|
||||
<div class="btn-wrapper">
|
||||
<ng-template appHasRole [appHasRole]="['iam.policy.write']">
|
||||
<button [routerLink]="[ 'policy', PolicyComponentType.LABEL ]"
|
||||
<button
|
||||
[routerLink]="[type == PolicyGridType.IAM ? '/iam' : type == PolicyGridType.ORG ? '/org' : '','policy', PolicyComponentType.LABEL ]"
|
||||
mat-stroked-button>{{'POLICY.BTN_EDIT' | translate}}</button>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
@ -382,6 +382,7 @@ func mfaFromModel(mfa *usr_model.MultiFactor) *auth.MultiFactor {
|
||||
State: mfaStateFromModel(mfa.State),
|
||||
Type: mfaTypeFromModel(mfa.Type),
|
||||
Attribute: mfa.Attribute,
|
||||
Id: mfa.ID,
|
||||
}
|
||||
}
|
||||
|
||||
@ -431,7 +432,7 @@ func userChangesToAPI(changes *usr_model.UserChanges) (_ []*auth.Change) {
|
||||
func verifyWebAuthNFromModel(u2f *usr_model.WebAuthNToken) *auth.WebAuthNResponse {
|
||||
return &auth.WebAuthNResponse{
|
||||
Id: u2f.WebAuthNTokenID,
|
||||
PublicKey: u2f.PublicKey,
|
||||
PublicKey: u2f.CredentialCreationData,
|
||||
State: mfaStateFromModel(u2f.State),
|
||||
}
|
||||
}
|
||||
|
@ -501,8 +501,9 @@ func mfasFromModel(mfas []*usr_model.MultiFactor) []*management.UserMultiFactor
|
||||
|
||||
func mfaFromModel(mfa *usr_model.MultiFactor) *management.UserMultiFactor {
|
||||
return &management.UserMultiFactor{
|
||||
State: mfaStateFromModel(mfa.State),
|
||||
Type: mfaTypeFromModel(mfa.Type),
|
||||
State: mfaStateFromModel(mfa.State),
|
||||
Type: mfaTypeFromModel(mfa.Type),
|
||||
Attribute: mfa.Attribute,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ const (
|
||||
XContentTypeOptions = "x-content-type-options"
|
||||
ReferrerPolicy = "referrer-policy"
|
||||
FeaturePolicy = "feature-policy"
|
||||
PermissionsPolicy = "permissions-policy"
|
||||
|
||||
ZitadelOrgID = "x-zitadel-orgid"
|
||||
)
|
||||
|
@ -70,6 +70,7 @@ func (h *headers) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
headers.Set(http_utils.XContentTypeOptions, "nosniff")
|
||||
headers.Set(http_utils.ReferrerPolicy, "same-origin")
|
||||
headers.Set(http_utils.FeaturePolicy, "payment 'none'")
|
||||
headers.Set(http_utils.PermissionsPolicy, "payment=()")
|
||||
//PLANNED: add expect-ct
|
||||
|
||||
h.handler.ServeHTTP(w, r)
|
||||
|
@ -270,7 +270,7 @@ func (repo *AuthRequestRepo) BeginMFAU2FLogin(ctx context.Context, userID, authR
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return repo.UserEvents.BeginU2FLogin(ctx, userID, request)
|
||||
return repo.UserEvents.BeginU2FLogin(ctx, userID, request, true)
|
||||
}
|
||||
|
||||
func (repo *AuthRequestRepo) VerifyMFAU2F(ctx context.Context, userID, authRequestID, userAgentID string, credentialData []byte, info *model.BrowserInfo) (err error) {
|
||||
@ -280,7 +280,7 @@ func (repo *AuthRequestRepo) VerifyMFAU2F(ctx context.Context, userID, authReque
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return repo.UserEvents.VerifyMFAU2F(ctx, userID, credentialData, request)
|
||||
return repo.UserEvents.VerifyMFAU2F(ctx, userID, credentialData, request, true)
|
||||
}
|
||||
|
||||
func (repo *AuthRequestRepo) BeginPasswordlessLogin(ctx context.Context, userID, authRequestID, userAgentID string) (login *user_model.WebAuthNLogin, err error) {
|
||||
@ -290,7 +290,7 @@ func (repo *AuthRequestRepo) BeginPasswordlessLogin(ctx context.Context, userID,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return repo.UserEvents.BeginPasswordlessLogin(ctx, userID, request)
|
||||
return repo.UserEvents.BeginPasswordlessLogin(ctx, userID, request, true)
|
||||
}
|
||||
|
||||
func (repo *AuthRequestRepo) VerifyPasswordless(ctx context.Context, userID, authRequestID, userAgentID string, credentialData []byte, info *model.BrowserInfo) (err error) {
|
||||
@ -300,7 +300,7 @@ func (repo *AuthRequestRepo) VerifyPasswordless(ctx context.Context, userID, aut
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return repo.UserEvents.VerifyPasswordless(ctx, userID, credentialData, request)
|
||||
return repo.UserEvents.VerifyPasswordless(ctx, userID, credentialData, request, true)
|
||||
}
|
||||
|
||||
func (repo *AuthRequestRepo) LinkExternalUsers(ctx context.Context, authReqID, userAgentID string, info *model.BrowserInfo) (err error) {
|
||||
@ -786,7 +786,7 @@ func userSessionByIDs(ctx context.Context, provider userSessionViewProvider, eve
|
||||
if !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
session = &user_view_model.UserSessionView{}
|
||||
session = &user_view_model.UserSessionView{UserAgentID: agentID, UserID: user.ID}
|
||||
}
|
||||
events, err := eventProvider.UserEventsByID(ctx, user.ID, session.Sequence)
|
||||
if err != nil {
|
||||
@ -824,7 +824,9 @@ func userSessionByIDs(ctx context.Context, provider userSessionViewProvider, eve
|
||||
case es_model.UserRemoved:
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dG2fe", "Errors.User.NotActive")
|
||||
}
|
||||
sessionCopy.AppendEvent(event)
|
||||
if err := sessionCopy.AppendEvent(event); err != nil {
|
||||
return user_view_model.UserSessionToModel(&sessionCopy), nil
|
||||
}
|
||||
}
|
||||
return user_view_model.UserSessionToModel(&sessionCopy), nil
|
||||
}
|
||||
|
@ -1208,7 +1208,7 @@ func Test_userSessionByIDs(t *testing.T) {
|
||||
eventProvider: &mockEventErrUser{},
|
||||
user: &user_model.UserView{ID: "id"},
|
||||
},
|
||||
&user_model.UserSessionView{},
|
||||
&user_model.UserSessionView{UserID: "id"},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
|
@ -234,11 +234,11 @@ func (repo *UserRepo) ChangeMyPassword(ctx context.Context, old, new string) err
|
||||
return err
|
||||
}
|
||||
pwPolicyView := iam_es_model.PasswordComplexityViewToModel(policy)
|
||||
_, err = repo.UserEvents.ChangePassword(ctx, pwPolicyView, authz.GetCtxData(ctx).UserID, old, new)
|
||||
_, err = repo.UserEvents.ChangePassword(ctx, pwPolicyView, authz.GetCtxData(ctx).UserID, old, new, "")
|
||||
return err
|
||||
}
|
||||
|
||||
func (repo *UserRepo) ChangePassword(ctx context.Context, userID, old, new string) (err error) {
|
||||
func (repo *UserRepo) ChangePassword(ctx context.Context, userID, old, new, userAgentID string) (err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
policy, err := repo.View.PasswordComplexityPolicyByAggregateID(authz.GetCtxData(ctx).OrgID)
|
||||
@ -249,7 +249,7 @@ func (repo *UserRepo) ChangePassword(ctx context.Context, userID, old, new strin
|
||||
return err
|
||||
}
|
||||
pwPolicyView := iam_es_model.PasswordComplexityViewToModel(policy)
|
||||
_, err = repo.UserEvents.ChangePassword(ctx, pwPolicyView, userID, old, new)
|
||||
_, err = repo.UserEvents.ChangePassword(ctx, pwPolicyView, userID, old, new, userAgentID)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -263,7 +263,7 @@ func (repo *UserRepo) MyUserMFAs(ctx context.Context) ([]*model.MultiFactor, err
|
||||
mfas = append(mfas, &model.MultiFactor{Type: model.MFATypeOTP, State: user.OTPState})
|
||||
}
|
||||
for _, u2f := range user.U2FTokens {
|
||||
mfas = append(mfas, &model.MultiFactor{Type: model.MFATypeU2F, State: u2f.State, Attribute: u2f.Name})
|
||||
mfas = append(mfas, &model.MultiFactor{Type: model.MFATypeU2F, State: u2f.State, Attribute: u2f.Name, ID: u2f.TokenID})
|
||||
}
|
||||
return mfas, nil
|
||||
}
|
||||
@ -290,12 +290,12 @@ func (repo *UserRepo) AddMyMFAOTP(ctx context.Context) (*model.OTP, error) {
|
||||
return repo.UserEvents.AddOTP(ctx, authz.GetCtxData(ctx).UserID, accountName)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) VerifyMFAOTPSetup(ctx context.Context, userID, code string) error {
|
||||
return repo.UserEvents.CheckMFAOTPSetup(ctx, userID, code)
|
||||
func (repo *UserRepo) VerifyMFAOTPSetup(ctx context.Context, userID, code, userAgentID string) error {
|
||||
return repo.UserEvents.CheckMFAOTPSetup(ctx, userID, code, userAgentID)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) VerifyMyMFAOTPSetup(ctx context.Context, code string) error {
|
||||
return repo.UserEvents.CheckMFAOTPSetup(ctx, authz.GetCtxData(ctx).UserID, code)
|
||||
return repo.UserEvents.CheckMFAOTPSetup(ctx, authz.GetCtxData(ctx).UserID, code, "")
|
||||
}
|
||||
|
||||
func (repo *UserRepo) RemoveMyMFAOTP(ctx context.Context) error {
|
||||
@ -303,19 +303,19 @@ func (repo *UserRepo) RemoveMyMFAOTP(ctx context.Context) error {
|
||||
}
|
||||
|
||||
func (repo *UserRepo) AddMFAU2F(ctx context.Context, userID string) (*model.WebAuthNToken, error) {
|
||||
return repo.UserEvents.AddU2F(ctx, userID)
|
||||
return repo.UserEvents.AddU2F(ctx, userID, true)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) AddMyMFAU2F(ctx context.Context) (*model.WebAuthNToken, error) {
|
||||
return repo.UserEvents.AddU2F(ctx, authz.GetCtxData(ctx).UserID)
|
||||
return repo.UserEvents.AddU2F(ctx, authz.GetCtxData(ctx).UserID, false)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) VerifyMFAU2FSetup(ctx context.Context, userID, tokenName string, credentialData []byte) error {
|
||||
return repo.UserEvents.VerifyU2FSetup(ctx, userID, tokenName, credentialData)
|
||||
func (repo *UserRepo) VerifyMFAU2FSetup(ctx context.Context, userID, tokenName, userAgentID string, credentialData []byte) error {
|
||||
return repo.UserEvents.VerifyU2FSetup(ctx, userID, tokenName, userAgentID, credentialData)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) VerifyMyMFAU2FSetup(ctx context.Context, tokenName string, credentialData []byte) error {
|
||||
return repo.UserEvents.VerifyU2FSetup(ctx, authz.GetCtxData(ctx).UserID, tokenName, credentialData)
|
||||
return repo.UserEvents.VerifyU2FSetup(ctx, authz.GetCtxData(ctx).UserID, tokenName, "", credentialData)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) RemoveMFAU2F(ctx context.Context, userID, webAuthNTokenID string) error {
|
||||
@ -327,19 +327,19 @@ func (repo *UserRepo) RemoveMyMFAU2F(ctx context.Context, webAuthNTokenID string
|
||||
}
|
||||
|
||||
func (repo *UserRepo) AddPasswordless(ctx context.Context, userID string) (*model.WebAuthNToken, error) {
|
||||
return repo.UserEvents.AddPasswordless(ctx, userID)
|
||||
return repo.UserEvents.AddPasswordless(ctx, userID, true)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) AddMyPasswordless(ctx context.Context) (*model.WebAuthNToken, error) {
|
||||
return repo.UserEvents.AddPasswordless(ctx, authz.GetCtxData(ctx).UserID)
|
||||
return repo.UserEvents.AddPasswordless(ctx, authz.GetCtxData(ctx).UserID, false)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) VerifyPasswordlessSetup(ctx context.Context, userID, tokenName string, credentialData []byte) error {
|
||||
return repo.UserEvents.VerifyPasswordlessSetup(ctx, userID, tokenName, credentialData)
|
||||
func (repo *UserRepo) VerifyPasswordlessSetup(ctx context.Context, userID, tokenName, userAgentID string, credentialData []byte) error {
|
||||
return repo.UserEvents.VerifyPasswordlessSetup(ctx, userID, tokenName, userAgentID, credentialData)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) VerifyMyPasswordlessSetup(ctx context.Context, tokenName string, credentialData []byte) error {
|
||||
return repo.UserEvents.VerifyPasswordlessSetup(ctx, authz.GetCtxData(ctx).UserID, tokenName, credentialData)
|
||||
return repo.UserEvents.VerifyPasswordlessSetup(ctx, authz.GetCtxData(ctx).UserID, tokenName, "", credentialData)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) RemovePasswordless(ctx context.Context, userID, webAuthNTokenID string) error {
|
||||
@ -391,7 +391,7 @@ func (repo *UserRepo) RequestPasswordReset(ctx context.Context, loginname string
|
||||
return repo.UserEvents.RequestSetPassword(ctx, user.ID, model.NotificationTypeEmail)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) SetPassword(ctx context.Context, userID, code, password string) error {
|
||||
func (repo *UserRepo) SetPassword(ctx context.Context, userID, code, password, userAgentID string) error {
|
||||
policy, err := repo.View.PasswordComplexityPolicyByAggregateID(authz.GetCtxData(ctx).OrgID)
|
||||
if errors.IsNotFound(err) {
|
||||
policy, err = repo.View.PasswordComplexityPolicyByAggregateID(repo.SystemDefaults.IamID)
|
||||
@ -400,7 +400,7 @@ func (repo *UserRepo) SetPassword(ctx context.Context, userID, code, password st
|
||||
return err
|
||||
}
|
||||
pwPolicyView := iam_es_model.PasswordComplexityViewToModel(policy)
|
||||
return repo.UserEvents.SetPassword(ctx, pwPolicyView, userID, code, password)
|
||||
return repo.UserEvents.SetPassword(ctx, pwPolicyView, userID, code, password, userAgentID)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) SignOut(ctx context.Context, agentID string) error {
|
||||
|
@ -93,7 +93,9 @@ func (u *UserSession) Reduce(event *models.Event) (err error) {
|
||||
return u.view.ProcessedUserSessionSequence(event.Sequence, event.CreationDate)
|
||||
}
|
||||
for _, session := range sessions {
|
||||
session.AppendEvent(event)
|
||||
if err := session.AppendEvent(event); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := u.fillUserInfo(session, event.AggregateID); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -116,7 +118,9 @@ func (u *UserSession) OnSuccess() error {
|
||||
}
|
||||
|
||||
func (u *UserSession) updateSession(session *view_model.UserSessionView, event *models.Event) error {
|
||||
session.AppendEvent(event)
|
||||
if err := session.AppendEvent(event); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := u.fillUserInfo(session, event.AggregateID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -16,8 +16,8 @@ type UserRepository interface {
|
||||
SkipMFAInit(ctx context.Context, userID string) error
|
||||
|
||||
RequestPasswordReset(ctx context.Context, username string) error
|
||||
SetPassword(ctx context.Context, userID, code, password string) error
|
||||
ChangePassword(ctx context.Context, userID, old, new string) error
|
||||
SetPassword(ctx context.Context, userID, code, password, userAgentID string) error
|
||||
ChangePassword(ctx context.Context, userID, old, new, userAgentID string) error
|
||||
|
||||
VerifyEmail(ctx context.Context, userID, code string) error
|
||||
ResendEmailVerificationMail(ctx context.Context, userID string) error
|
||||
@ -26,14 +26,14 @@ type UserRepository interface {
|
||||
ResendInitVerificationMail(ctx context.Context, userID string) error
|
||||
|
||||
AddMFAOTP(ctx context.Context, userID string) (*model.OTP, error)
|
||||
VerifyMFAOTPSetup(ctx context.Context, userID, code string) error
|
||||
VerifyMFAOTPSetup(ctx context.Context, userID, code, userAgentID string) error
|
||||
|
||||
AddMFAU2F(ctx context.Context, id string) (*model.WebAuthNToken, error)
|
||||
VerifyMFAU2FSetup(ctx context.Context, userID, tokenName string, credentialData []byte) error
|
||||
VerifyMFAU2FSetup(ctx context.Context, userID, tokenName, userAgentID string, credentialData []byte) error
|
||||
RemoveMFAU2F(ctx context.Context, userID, webAuthNTokenID string) error
|
||||
|
||||
AddPasswordless(ctx context.Context, id string) (*model.WebAuthNToken, error)
|
||||
VerifyPasswordlessSetup(ctx context.Context, userID, tokenName string, credentialData []byte) error
|
||||
VerifyPasswordlessSetup(ctx context.Context, userID, tokenName, userAgentID string, credentialData []byte) error
|
||||
RemovePasswordless(ctx context.Context, userID, webAuthNTokenID string) error
|
||||
|
||||
ChangeUsername(ctx context.Context, userID, username string) error
|
||||
|
@ -92,7 +92,8 @@ type TemplateData struct {
|
||||
}
|
||||
|
||||
type WebAuthN struct {
|
||||
ID string
|
||||
Origin string
|
||||
DisplayName string
|
||||
ID string
|
||||
OriginLogin string
|
||||
OriginConsole string
|
||||
DisplayName string
|
||||
}
|
||||
|
@ -217,10 +217,14 @@ func (repo *UserRepo) UserMFAs(ctx context.Context, userID string) ([]*usr_model
|
||||
if user.HumanView == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-xx0hV", "Errors.User.NotHuman")
|
||||
}
|
||||
if user.OTPState == usr_model.MFAStateUnspecified {
|
||||
return []*usr_model.MultiFactor{}, nil
|
||||
mfas := make([]*usr_model.MultiFactor, 0)
|
||||
if user.OTPState != usr_model.MFAStateUnspecified {
|
||||
mfas = append(mfas, &usr_model.MultiFactor{Type: usr_model.MFATypeOTP, State: user.OTPState})
|
||||
}
|
||||
return []*usr_model.MultiFactor{{Type: usr_model.MFATypeOTP, State: user.OTPState}}, nil
|
||||
for _, u2f := range user.U2FTokens {
|
||||
mfas = append(mfas, &usr_model.MultiFactor{Type: usr_model.MFATypeU2F, State: u2f.State, Attribute: u2f.Name, ID: u2f.TokenID})
|
||||
}
|
||||
return mfas, nil
|
||||
}
|
||||
|
||||
func (repo *UserRepo) RemoveOTP(ctx context.Context, userID string) error {
|
||||
|
@ -107,6 +107,7 @@ func (step *Step1) orgs(ctx context.Context, orgs []Org) error {
|
||||
return err
|
||||
}
|
||||
step.createdOrgs[iamOrg.Name] = org
|
||||
logging.LogWithFields("SETUP-HR2gh", "name", org.Name, "ID", org.AggregateID).Info("created organisation")
|
||||
|
||||
var policy *iam_model.OrgIAMPolicyView
|
||||
if iamOrg.OrgIamPolicy {
|
||||
|
@ -320,8 +320,32 @@ EventTypes:
|
||||
check:
|
||||
succeeded: Multifaktor OTP Verifikation erfolgreich
|
||||
failed: Multifaktor OTP Verifikation fehlgeschlagen
|
||||
u2f:
|
||||
token:
|
||||
added: Multifaktor U2F Token hinzugefügt
|
||||
verified: Multifaktor U2F Token verifiziert
|
||||
removed: Multifaktor U2F Token entfernt
|
||||
begin:
|
||||
login: Multifaktor U2F Verifikation begonnen
|
||||
check:
|
||||
succeeded: Multifaktor U2F Verifikation erfolgreich
|
||||
failed: Multifaktor U2F Verifikation fehlgeschlagen
|
||||
signcount:
|
||||
changed: Prüfsumme des Multifaktor U2F Tokens wurde verändert
|
||||
init:
|
||||
skipped: Multifaktor Initialisierung übersprungen
|
||||
passwordless:
|
||||
token:
|
||||
added: Token für Passwortlos Login hinzugefügt
|
||||
verified: Token für Passwortlos Login verifiziert
|
||||
removed: Token für Passwortlos Login entfernt
|
||||
begin:
|
||||
login: Verifikation für Passwortlos Login begonnen
|
||||
check:
|
||||
succeeded: Verifikation für Passwortlos Login erfolgreich
|
||||
failed: Verifikation für Passwortlos Login fehlgeschlagen
|
||||
signcount:
|
||||
changed: Prüfsumme des Tokens für Passwortlos Login wurde verändert
|
||||
signed:
|
||||
out: Benutzer erfolgreich abgemeldet
|
||||
locked: Benutzer gesperrt
|
||||
|
@ -101,6 +101,7 @@ Errors:
|
||||
IDP:
|
||||
InvalidSearchQuery: Ungültiger Suchparameter
|
||||
LoginPolicy:
|
||||
NotFound: Login Policy not found
|
||||
Invalid: Login Policy is invalid
|
||||
NotExisting: Login Policy not existig
|
||||
AlreadyExists: Login Policy already exists
|
||||
@ -111,9 +112,20 @@ Errors:
|
||||
NotExisting: Multifactor not existing
|
||||
Unspecified: Multifactor invalid
|
||||
PasswordComplexity:
|
||||
Empty: Passwort Complexity Policy is empty
|
||||
NotExisting: Passwort Complexity Policy doesn't exist
|
||||
AlreadyExists: Passwort Complexity Policy already exists
|
||||
NotFound: Password Complexity Policy not found
|
||||
Empty: Password Complexity Policy is empty
|
||||
NotExisting: Password Complexity Policy doesn't exist
|
||||
AlreadyExists: Password Complexity Policy already exists
|
||||
PasswordLockout:
|
||||
NotFound: Password Lockout Policy not found
|
||||
Empty: Passwort Lockout Policy is empty
|
||||
NotExisting: Passwort Lockout Policy doesn't exist
|
||||
AlreadyExists: Passwort Lockout Policy already exists
|
||||
PasswordAge:
|
||||
NotFound: Password Age Policy not found
|
||||
Empty: Password Age Policy is empty
|
||||
NotExisting: Password Age Policy doesn't exist
|
||||
AlreadyExists: Password Age Policy already exists
|
||||
OrgIAM:
|
||||
Empty: Org IAM Policy is empty
|
||||
NotExisting: Org IAM Policy doesn't exist
|
||||
@ -308,8 +320,32 @@ EventTypes:
|
||||
check:
|
||||
succeeded: Multifactor OTP check succeeded
|
||||
failed: Multifactor OTP check failed
|
||||
u2f:
|
||||
token:
|
||||
added: Multifactor U2F Token added
|
||||
verified: Multifactor U2F Token verified
|
||||
removed: Multifactor U2F Token removed
|
||||
begin:
|
||||
login: Multifactor U2F check started
|
||||
check:
|
||||
succeeded: Multifactor U2F check succeeded
|
||||
failed: Multifactor U2F check failed
|
||||
signcount:
|
||||
changed: Checksum of the Multifactor U2F Token has been changed
|
||||
init:
|
||||
skipped: Multifactor initialisation skipped
|
||||
passwordless:
|
||||
token:
|
||||
added: Token for Passwordless Login added
|
||||
verified: Token for Passwordless Login verified
|
||||
removed: Token for Passwordless Login removed
|
||||
begin:
|
||||
login: Passwordless Login check started
|
||||
check:
|
||||
succeeded: Passwordless Login check succeeded
|
||||
failed: Passwordless Login check failed
|
||||
signcount:
|
||||
changed: Checksum of the Passwordless Login Token has been changed
|
||||
signed:
|
||||
out: User signed out
|
||||
locked: User locked
|
||||
|
@ -3,6 +3,7 @@ package handler
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
http_mw "github.com/caos/zitadel/internal/api/http/middleware"
|
||||
"github.com/caos/zitadel/internal/auth_request/model"
|
||||
)
|
||||
|
||||
@ -24,7 +25,8 @@ func (l *Login) handleChangePassword(w http.ResponseWriter, r *http.Request) {
|
||||
l.renderError(w, r, authReq, err)
|
||||
return
|
||||
}
|
||||
err = l.authRepo.ChangePassword(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, data.OldPassword, data.NewPassword)
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
err = l.authRepo.ChangePassword(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, data.OldPassword, data.NewPassword, userAgentID)
|
||||
if err != nil {
|
||||
l.renderChangePassword(w, r, authReq, err)
|
||||
return
|
||||
|
@ -3,6 +3,7 @@ package handler
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
http_mw "github.com/caos/zitadel/internal/api/http/middleware"
|
||||
"github.com/caos/zitadel/internal/auth_request/model"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
)
|
||||
@ -67,7 +68,8 @@ func (l *Login) checkPWCode(w http.ResponseWriter, r *http.Request, authReq *mod
|
||||
if authReq != nil {
|
||||
userOrg = authReq.UserOrgID
|
||||
}
|
||||
err = l.authRepo.SetPassword(setContext(r.Context(), userOrg), data.UserID, data.Code, data.Password)
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
err = l.authRepo.SetPassword(setContext(r.Context(), userOrg), data.UserID, data.Code, data.Password, userAgentID)
|
||||
if err != nil {
|
||||
l.renderInitPassword(w, r, authReq, data.UserID, "", err)
|
||||
return
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"encoding/base64"
|
||||
"net/http"
|
||||
|
||||
http_mw "github.com/caos/zitadel/internal/api/http/middleware"
|
||||
"github.com/caos/zitadel/internal/auth_request/model"
|
||||
user_model "github.com/caos/zitadel/internal/user/model"
|
||||
)
|
||||
@ -12,6 +13,11 @@ const (
|
||||
tmplMFAU2FInit = "mfainitu2f"
|
||||
)
|
||||
|
||||
type u2fInitData struct {
|
||||
webAuthNData
|
||||
MFAType model.MFAType
|
||||
}
|
||||
|
||||
func (l *Login) renderRegisterU2F(w http.ResponseWriter, r *http.Request, authReq *model.AuthRequest, err error) {
|
||||
var errType, errMessage, credentialData string
|
||||
var u2f *user_model.WebAuthNToken
|
||||
@ -24,9 +30,12 @@ func (l *Login) renderRegisterU2F(w http.ResponseWriter, r *http.Request, authRe
|
||||
if u2f != nil {
|
||||
credentialData = base64.RawURLEncoding.EncodeToString(u2f.CredentialCreationData)
|
||||
}
|
||||
data := &webAuthNData{
|
||||
userData: l.getUserData(r, authReq, "Register WebAuthNToken", errType, errMessage),
|
||||
CredentialCreationData: credentialData,
|
||||
data := &u2fInitData{
|
||||
webAuthNData: webAuthNData{
|
||||
userData: l.getUserData(r, authReq, "Register WebAuthNToken", errType, errMessage),
|
||||
CredentialCreationData: credentialData,
|
||||
},
|
||||
MFAType: model.MFATypeU2F,
|
||||
}
|
||||
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplMFAU2FInit], data, nil)
|
||||
}
|
||||
@ -38,17 +47,14 @@ func (l *Login) handleRegisterU2F(w http.ResponseWriter, r *http.Request) {
|
||||
l.renderError(w, r, authReq, err)
|
||||
return
|
||||
}
|
||||
if data.Recreate {
|
||||
l.renderRegisterU2F(w, r, authReq, nil)
|
||||
return
|
||||
}
|
||||
credData, err := base64.URLEncoding.DecodeString(data.CredentialData)
|
||||
if err != nil {
|
||||
l.renderRegisterU2F(w, r, authReq, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = l.authRepo.VerifyMFAU2FSetup(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, data.Name, credData); err != nil {
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
if err = l.authRepo.VerifyMFAU2FSetup(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, data.Name, userAgentID, credData); err != nil {
|
||||
l.renderRegisterU2F(w, r, authReq, err)
|
||||
return
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
svg "github.com/ajstarks/svgo"
|
||||
"github.com/boombuler/barcode/qr"
|
||||
|
||||
http_mw "github.com/caos/zitadel/internal/api/http/middleware"
|
||||
"github.com/caos/zitadel/internal/auth_request/model"
|
||||
"github.com/caos/zitadel/internal/qrcode"
|
||||
)
|
||||
@ -47,7 +48,8 @@ func (l *Login) handleMFAInitVerify(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (l *Login) handleOTPVerify(w http.ResponseWriter, r *http.Request, authReq *model.AuthRequest, data *mfaInitVerifyData) *mfaVerifyData {
|
||||
err := l.authRepo.VerifyMFAOTPSetup(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, data.Code)
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
err := l.authRepo.VerifyMFAOTPSetup(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, data.Code, userAgentID)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -35,6 +35,15 @@ func (l *Login) handleMFAVerify(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (l *Login) renderMFAVerify(w http.ResponseWriter, r *http.Request, authReq *model.AuthRequest, verificationStep *model.MFAVerificationStep, err error) {
|
||||
if verificationStep == nil {
|
||||
l.renderError(w, r, authReq, err)
|
||||
return
|
||||
}
|
||||
provider := verificationStep.MFAProviders[len(verificationStep.MFAProviders)-1]
|
||||
l.renderMFAVerifySelected(w, r, authReq, verificationStep, provider, err)
|
||||
}
|
||||
|
||||
func (l *Login) renderMFAVerifySelected(w http.ResponseWriter, r *http.Request, authReq *model.AuthRequest, verificationStep *model.MFAVerificationStep, selectedProvider model.MFAType, err error) {
|
||||
var errType, errMessage string
|
||||
if err != nil {
|
||||
errMessage = l.getErrorMessage(r, err)
|
||||
@ -44,13 +53,23 @@ func (l *Login) renderMFAVerify(w http.ResponseWriter, r *http.Request, authReq
|
||||
l.renderError(w, r, authReq, err)
|
||||
return
|
||||
}
|
||||
switch verificationStep.MFAProviders[len(verificationStep.MFAProviders)-1] {
|
||||
switch selectedProvider {
|
||||
case model.MFATypeU2F:
|
||||
l.renderU2FVerification(w, r, authReq, nil)
|
||||
l.renderU2FVerification(w, r, authReq, removeSelectedProviderFromList(verificationStep.MFAProviders, model.MFATypeU2F), nil)
|
||||
return
|
||||
case model.MFATypeOTP:
|
||||
data.MFAProviders = verificationStep.MFAProviders
|
||||
data.MFAProviders = removeSelectedProviderFromList(verificationStep.MFAProviders, model.MFATypeOTP)
|
||||
data.SelectedMFAProvider = model.MFATypeOTP
|
||||
}
|
||||
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplMFAVerify], data, nil)
|
||||
}
|
||||
|
||||
func removeSelectedProviderFromList(providers []model.MFAType, selected model.MFAType) []model.MFAType {
|
||||
for i := len(providers) - 1; i >= 0; i-- {
|
||||
if providers[i] == selected {
|
||||
copy(providers[i:], providers[i+1:])
|
||||
return providers[:len(providers)-1]
|
||||
}
|
||||
}
|
||||
return providers
|
||||
}
|
||||
|
@ -13,7 +13,18 @@ const (
|
||||
tmplU2FVerification = "u2fverification"
|
||||
)
|
||||
|
||||
func (l *Login) renderU2FVerification(w http.ResponseWriter, r *http.Request, authReq *model.AuthRequest, err error) {
|
||||
type mfaU2FData struct {
|
||||
webAuthNData
|
||||
MFAProviders []model.MFAType
|
||||
SelectedProvider model.MFAType
|
||||
}
|
||||
|
||||
type mfaU2FFormData struct {
|
||||
webAuthNFormData
|
||||
SelectedProvider model.MFAType `schema:"provider"`
|
||||
}
|
||||
|
||||
func (l *Login) renderU2FVerification(w http.ResponseWriter, r *http.Request, authReq *model.AuthRequest, providers []model.MFAType, err error) {
|
||||
var errType, errMessage, credentialData string
|
||||
var webAuthNLogin *user_model.WebAuthNLogin
|
||||
if err == nil {
|
||||
@ -26,33 +37,42 @@ func (l *Login) renderU2FVerification(w http.ResponseWriter, r *http.Request, au
|
||||
if webAuthNLogin != nil {
|
||||
credentialData = base64.RawURLEncoding.EncodeToString(webAuthNLogin.CredentialAssertionData)
|
||||
}
|
||||
data := &webAuthNData{
|
||||
userData: l.getUserData(r, authReq, "Login WebAuthNToken", errType, errMessage),
|
||||
CredentialCreationData: credentialData,
|
||||
data := &mfaU2FData{
|
||||
webAuthNData: webAuthNData{
|
||||
userData: l.getUserData(r, authReq, "Login WebAuthNToken", errType, errMessage),
|
||||
CredentialCreationData: credentialData,
|
||||
},
|
||||
MFAProviders: providers,
|
||||
SelectedProvider: -1,
|
||||
}
|
||||
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplU2FVerification], data, nil)
|
||||
}
|
||||
|
||||
func (l *Login) handleU2FVerification(w http.ResponseWriter, r *http.Request) {
|
||||
formData := new(webAuthNFormData)
|
||||
formData := new(mfaU2FFormData)
|
||||
authReq, err := l.getAuthRequestAndParseData(r, formData)
|
||||
if err != nil {
|
||||
l.renderError(w, r, authReq, err)
|
||||
return
|
||||
}
|
||||
if formData.Recreate {
|
||||
l.renderU2FVerification(w, r, authReq, nil)
|
||||
step, ok := authReq.PossibleSteps[0].(*model.MFAVerificationStep)
|
||||
if !ok {
|
||||
l.renderError(w, r, authReq, err)
|
||||
return
|
||||
}
|
||||
if formData.CredentialData == "" {
|
||||
l.renderMFAVerifySelected(w, r, authReq, step, formData.SelectedProvider, nil)
|
||||
return
|
||||
}
|
||||
credData, err := base64.URLEncoding.DecodeString(formData.CredentialData)
|
||||
if err != nil {
|
||||
l.renderU2FVerification(w, r, authReq, err)
|
||||
l.renderU2FVerification(w, r, authReq, step.MFAProviders, err)
|
||||
return
|
||||
}
|
||||
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
|
||||
err = l.authRepo.VerifyMFAU2F(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, authReq.ID, userAgentID, credData, model.BrowserInfoFromRequest(r))
|
||||
if err != nil {
|
||||
l.renderU2FVerification(w, r, authReq, err)
|
||||
l.renderU2FVerification(w, r, authReq, step.MFAProviders, err)
|
||||
return
|
||||
}
|
||||
l.renderNextStep(w, r, authReq)
|
||||
|
@ -40,10 +40,6 @@ func (l *Login) handlePasswordlessVerification(w http.ResponseWriter, r *http.Re
|
||||
l.renderError(w, r, authReq, err)
|
||||
return
|
||||
}
|
||||
if formData.Recreate {
|
||||
l.renderPasswordlessVerification(w, r, authReq, nil)
|
||||
return
|
||||
}
|
||||
credData, err := base64.URLEncoding.DecodeString(formData.CredentialData)
|
||||
if err != nil {
|
||||
l.renderPasswordlessVerification(w, r, authReq, err)
|
||||
|
@ -8,5 +8,4 @@ type webAuthNData struct {
|
||||
type webAuthNFormData struct {
|
||||
CredentialData string `schema:"credentialData"`
|
||||
Name string `schema:"name"`
|
||||
Recreate bool `schema:"recreate"`
|
||||
}
|
||||
|
@ -63,6 +63,11 @@ InitUserDone:
|
||||
Title: User aktiviert
|
||||
Description: EMail verifiziert und Passwort erfolgreich gesetzt
|
||||
|
||||
MFA:
|
||||
Provider0: OTP (One Time Password)
|
||||
Provider1: U2F (Universal 2nd Factor)
|
||||
ChooseOther: oder wähle eine andere Option aus
|
||||
|
||||
MFAPrompt:
|
||||
Title: Multifaktor hinzufügen
|
||||
Description: Möchtest du einen Mulitfaktor hinzufügen?
|
||||
@ -78,7 +83,7 @@ MFAInitVerify:
|
||||
|
||||
MFAInitDone:
|
||||
Title: Multifaktor Verifizierung erstellt
|
||||
Description: Multifikator Verifizierung erfolgreich abgeschlossen. Der Multifaktor muss bei jeder Anmeldung eingegeben werden, dies beinhaltet auch den aktuellen Authentifizierungs Prozess.
|
||||
Description: Multifikator Verifizierung erfolgreich abgeschlossen. Der Multifaktor muss bei jeder Anmeldung eingegeben werden.
|
||||
|
||||
MFAInitU2F:
|
||||
Title: Multifaktor U2F / WebAuthN hinzufügen
|
||||
|
@ -63,6 +63,11 @@ InitUserDone:
|
||||
Title: User activated
|
||||
Description: Email verified and Password successfully set
|
||||
|
||||
MFA:
|
||||
Provider0: OTP (One Time Password)
|
||||
Provider1: U2F (Universal 2nd Factor)
|
||||
ChooseOther: or choose an other option
|
||||
|
||||
MFAPrompt:
|
||||
Title: Multifactor Setup
|
||||
Description: Would you like to setup multifactor authentication?
|
||||
@ -78,7 +83,7 @@ MFAInitVerify:
|
||||
|
||||
MFAInitDone:
|
||||
Title: Multifcator Verification done
|
||||
Description: Multifactor verification successfully done. The multifactor has to be entered on each login, even in the actual authentification process.
|
||||
Description: Multifactor verification successfully done. The multifactor has to be entered on each login.
|
||||
|
||||
MFAInitU2F:
|
||||
Title: Multifactor Setup U2F / WebAuthN
|
||||
|
@ -3,6 +3,7 @@ function disableSubmit(checks, button) {
|
||||
let inputs = form.getElementsByTagName('input');
|
||||
button.disabled = true;
|
||||
addRequiredEventListener(inputs, checks, form, button);
|
||||
disableDoubleSubmit(form, button);
|
||||
}
|
||||
|
||||
function addRequiredEventListener(inputs, checks, form, button) {
|
||||
@ -20,6 +21,13 @@ function addRequiredEventListener(inputs, checks, form, button) {
|
||||
}
|
||||
}
|
||||
|
||||
function disableDoubleSubmit(form, button) {
|
||||
form.addEventListener('submit', function() {
|
||||
document.body.classList.add('waiting');
|
||||
button.disabled = true;
|
||||
})
|
||||
}
|
||||
|
||||
function toggleButton(checks, form, inputs, button) {
|
||||
if (checks !== undefined) {
|
||||
if (checks() === false) {
|
||||
|
@ -75,11 +75,15 @@
|
||||
font-family: Lato;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0 0 100px 0;
|
||||
}
|
||||
body.waiting * {
|
||||
cursor: wait !important;
|
||||
}
|
||||
|
||||
html {
|
||||
width: 100%;
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/fonts.scss","../../scss/main.scss","../../scss/caos/variables.scss","../../scss/variables.scss"],"names":[],"mappings":"AACA;EACI;EACA;;AAIJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;AAA6D;EAC7D;;AC5EJ;EACI;EACA,aCMW;EDLX;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;EACA,kBCDc;EDEd,OCDQ;EDER;EACA;EACA;;;AAMJ;EACI,OCXQ;EDYR,aClBS;EDmBT;EACA,WEzBS;EF0BT;;;AAGJ;EACI,OCnBQ;EDoBR,aC1BS;ED2BT;EACA,WEhCU;;;AFmCd;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AAIR;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;;;AAGJ;EACI,OCvDW;EDwDX;EACA;;AAEA;EACI,OC3DY;;AD8DhB;EACI;;;AAIR;EACI,kBCvEc;EDwEd,OCtEW;EDuEX;EACA;EACA;EACA;EACA,QExFU;EFyFV;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI,kBCpFY;EDqFZ,OCxFU;EDyFV;;AAGJ;EACI,kBC3FO;ED4FP,OC7FI;ED8FJ;;AACA;EACI,kBC9FQ;;ADkGhB;EACI,kBExFW;EFyFX;;AAEA;EACI,kBE5FO;EF6FP;;AAIR;EACI;EACA;EACA;EACA;EACA,OEhGa;EFiGb,kBEhGmB;;AFkGnB;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;;;AAOZ;EACI,kBE9HmB;EF+HnB,OC7IQ;ED8IR,QE1JU;EF2JV;EACA;EACA;;;AAIA;EACI;EACA;EACA;EACA;EEzJN;;AACA;EFoJE;IEnJA;IACA;;;AF0JA;EE7JF;;AACA;EF4JE;IE3JA;IACA;;;;AFiKA;EACI;EACA;;AAGJ;EACI;EACA;;AAEA;EACI,WEvLE;EFwLF;;AAGJ;EACI;EACA;EACA;EACA,OE1KC;;;AFgLT;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIR;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA,OC/NA;;ADmOR;EACI,OExNK;EFyNL;EACA;EACA;;AAEA;EACI;EACA;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA,OC9PI;ED+PJ;EACA;EACA;EACA;;AAEA;EACI;EACA,kBExPW;;AF2Pf;EACI;;AAIR;EACI;;AAKA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA,cEjRO;EFkRP;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;AAKR;EACI;;AAEA;EACI;;AAEA;EACI;;AAEJ;EACI,OE7SP;;AFoTL;EACI;;AAEJ;EACI;EACA;EACA;EACA;EEvUV;;AACA;EFkUM;IEjUJ;IACA;;;AFyUQ;EACI;EACA;EE9Ud;;AACA;EF2UU;IE1UR;IACA;;;AFgVI;EACI;EACA;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA,OErVN;;AF0VE;EACI,OE5VL;;AFiWP;EACI;;AACA;EACI;EACA;;;AAKZ;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI,MCxYI;;AD2YR;EACI,MC7YU;;;ADkZd;EACI;EACA;;;AAIR;EAEQ;EAEJ;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;AAAkB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;AACA;EACA;AAEA;EACA;AAEA;EACA;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI,OE5aO;;;AF+aX;EACI;;;AAGJ;EACI","file":"dark.css"}
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/fonts.scss","../../scss/main.scss","../../scss/caos/variables.scss","../../scss/variables.scss"],"names":[],"mappings":"AACA;EACI;EACA;;AAIJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;AAA6D;EAC7D;;AC5EJ;EACI;EACA,aCMW;EDLX;EACA;EACA;;;AAGJ;EACI;;AAEA;EACI;;;AAIR;EACI;EACA;EACA;EACA,kBCNc;EDOd,OCNQ;EDOR;EACA;EACA;;;AAMJ;EACI,OChBQ;EDiBR,aCvBS;EDwBT;EACA,WE9BS;EF+BT;;;AAGJ;EACI,OCxBQ;EDyBR,aC/BS;EDgCT;EACA,WErCU;;;AFwCd;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AAIR;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;;;AAGJ;EACI,OC5DW;ED6DX;EACA;;AAEA;EACI,OChEY;;ADmEhB;EACI;;;AAIR;EACI,kBC5Ec;ED6Ed,OC3EW;ED4EX;EACA;EACA;EACA;EACA,QE7FU;EF8FV;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI,kBCzFY;ED0FZ,OC7FU;ED8FV;;AAGJ;EACI,kBChGO;EDiGP,OClGI;EDmGJ;;AACA;EACI,kBCnGQ;;ADuGhB;EACI,kBE7FW;EF8FX;;AAEA;EACI,kBEjGO;EFkGP;;AAIR;EACI;EACA;EACA;EACA;EACA,OErGa;EFsGb,kBErGmB;;AFuGnB;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;;;AAOZ;EACI,kBEnImB;EFoInB,OClJQ;EDmJR,QE/JU;EFgKV;EACA;EACA;;;AAIA;EACI;EACA;EACA;EACA;EE9JN;;AACA;EFyJE;IExJA;IACA;;;AF+JA;EElKF;;AACA;EFiKE;IEhKA;IACA;;;;AFsKA;EACI;EACA;;AAGJ;EACI;EACA;;AAEA;EACI,WE5LE;EF6LF;;AAGJ;EACI;EACA;EACA;EACA,OE/KC;;;AFqLT;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIR;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA,OCpOA;;ADwOR;EACI,OE7NK;EF8NL;EACA;EACA;;AAEA;EACI;EACA;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA,OCnQI;EDoQJ;EACA;EACA;EACA;;AAEA;EACI;EACA,kBE7PW;;AFgQf;EACI;;AAIR;EACI;;AAKA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA,cEtRO;EFuRP;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;AAKR;EACI;;AAEA;EACI;;AAEA;EACI;;AAEJ;EACI,OElTP;;AFyTL;EACI;;AAEJ;EACI;EACA;EACA;EACA;EE5UV;;AACA;EFuUM;IEtUJ;IACA;;;AF8UQ;EACI;EACA;EEnVd;;AACA;EFgVU;IE/UR;IACA;;;AFqVI;EACI;EACA;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA,OE1VN;;AF+VE;EACI,OEjWL;;AFsWP;EACI;;AACA;EACI;EACA;;;AAKZ;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI,MC7YI;;ADgZR;EACI,MClZU;;;ADuZd;EACI;EACA;;;AAIR;EAEQ;EAEJ;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;AAAkB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;AACA;EACA;AAEA;EACA;AAEA;EACA;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI,OEjbO;;;AFobX;EACI;;;AAGJ;EACI","file":"dark.css"}
|
@ -75,11 +75,15 @@
|
||||
font-family: Lato;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0 0 100px 0;
|
||||
}
|
||||
body.waiting * {
|
||||
cursor: wait !important;
|
||||
}
|
||||
|
||||
html {
|
||||
width: 100%;
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/fonts.scss","../../scss/main.scss","../../scss/caos/variables.scss","../../scss/variables.scss","../../scss/light.scss"],"names":[],"mappings":"AACA;EACI;EACA;;AAIJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;AAA6D;EAC7D;;AC5EJ;EACI;EACA,aCMW;EDLX;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;EACA,kBCDc;EDEd,OCDQ;EDER;EACA;EACA;;;AAMJ;EACI,OCXQ;EDYR,aClBS;EDmBT;EACA,WEzBS;EF0BT;;;AAGJ;EACI,OCnBQ;EDoBR,aC1BS;ED2BT;EACA,WEhCU;;;AFmCd;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AAIR;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;;;AAGJ;EACI,OCvDW;EDwDX;EACA;;AAEA;EACI,OC3DY;;AD8DhB;EACI;;;AAIR;EACI,kBCvEc;EDwEd,OCtEW;EDuEX;EACA;EACA;EACA;EACA,QExFU;EFyFV;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI,kBCpFY;EDqFZ,OCxFU;EDyFV;;AAGJ;EACI,kBC3FO;ED4FP,OC7FI;ED8FJ;;AACA;EACI,kBC9FQ;;ADkGhB;EACI,kBExFW;EFyFX;;AAEA;EACI,kBE5FO;EF6FP;;AAIR;EACI;EACA;EACA;EACA;EACA,OEhGa;EFiGb,kBEhGmB;;AFkGnB;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;;;AAOZ;EACI,kBE9HmB;EF+HnB,OC7IQ;ED8IR,QE1JU;EF2JV;EACA;EACA;;;AAIA;EACI;EACA;EACA;EACA;EEzJN;;AACA;EFoJE;IEnJA;IACA;;;AF0JA;EE7JF;;AACA;EF4JE;IE3JA;IACA;;;;AFiKA;EACI;EACA;;AAGJ;EACI;EACA;;AAEA;EACI,WEvLE;EFwLF;;AAGJ;EACI;EACA;EACA;EACA,OE1KC;;;AFgLT;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIR;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA,OC/NA;;ADmOR;EACI,OExNK;EFyNL;EACA;EACA;;AAEA;EACI;EACA;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA,OC9PI;ED+PJ;EACA;EACA;EACA;;AAEA;EACI;EACA,kBExPW;;AF2Pf;EACI;;AAIR;EACI;;AAKA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA,cEjRO;EFkRP;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;AAKR;EACI;;AAEA;EACI;;AAEA;EACI;;AAEJ;EACI,OE7SP;;AFoTL;EACI;;AAEJ;EACI;EACA;EACA;EACA;EEvUV;;AACA;EFkUM;IEjUJ;IACA;;;AFyUQ;EACI;EACA;EE9Ud;;AACA;EF2UU;IE1UR;IACA;;;AFgVI;EACI;EACA;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA,OErVN;;AF0VE;EACI,OE5VL;;AFiWP;EACI;;AACA;EACI;EACA;;;AAKZ;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI,MCxYI;;AD2YR;EACI,MC7YU;;;ADkZd;EACI;EACA;;;AAIR;EAEQ;EAEJ;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;AAAkB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;AACA;EACA;AAEA;EACA;AAEA;EACA;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI,OE5aO;;;AF+aX;EACI;;;AAGJ;EACI;;;AGzdJ;EACI,kBFeQ;EEdR,OFac;;AERd;EACI;;AAGJ;EACI,OFGU;;AEAd;EACI;EACA;EACA;;AAEA;EACI,kBFIa;EEHb;EACA,ODyBgB;;ACtBpB;EACI,kBFVG;EEWH,ODoBgB;ECnBhB;EACA;;AACA;EACI,kBFdI;;AEkBZ;EACI,kBDRO;ECSP;;AAEA;EACI,kBDZG;ECaH;;AAIR;EACI,OFhCM;;AEkCN;EACI;EACA,kBDHY;;ACQhB;EDxCV;;AACA;ECuCU;IDtCR;IACA;;;ACyCQ;EACI,kBDbY;;ACeZ;ED/Cd;;AACA;EC8Cc;ID7CZ;IACA;;;ACmDQ;EDtDV;;AACA;ECqDU;IDpDR;IACA;;;ACwDY;ED3Dd;;AACA;EC0Dc;IDzDZ;IACA;;;AC8DI;EACI,OD7Bc;EC8Bd,kBD7BoB;;AC+BpB;EACI;;AAKZ;EACI,kBD5CoB;EC6CpB,OF9EU;;AEkFV;EACI,MFnFM;;AEsFV;EACI,MFtFA;;AE0FR;EAEQ;;;AAMR;EACI,OFpGU;;AEwGb;EACI,ODhEM;;ACoEN;EACI,ODtEG;;;AC8EZ;EDrHF;;AACA;ECoHE;IDnHA;IACA;;;ACsHA;EDzHF;;AACA;ECwHE;IDvHA;IACA;;;;AC2HJ;EACI;;;AAGJ;EACI,OD5FY","file":"light.css"}
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/fonts.scss","../../scss/main.scss","../../scss/caos/variables.scss","../../scss/variables.scss","../../scss/light.scss"],"names":[],"mappings":"AACA;EACI;EACA;;AAIJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;AAA6D;EAC7D;;AC5EJ;EACI;EACA,aCMW;EDLX;EACA;EACA;;;AAGJ;EACI;;AAEA;EACI;;;AAIR;EACI;EACA;EACA;EACA,kBCNc;EDOd,OCNQ;EDOR;EACA;EACA;;;AAMJ;EACI,OChBQ;EDiBR,aCvBS;EDwBT;EACA,WE9BS;EF+BT;;;AAGJ;EACI,OCxBQ;EDyBR,aC/BS;EDgCT;EACA,WErCU;;;AFwCd;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AAIR;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;;;AAGJ;EACI,OC5DW;ED6DX;EACA;;AAEA;EACI,OChEY;;ADmEhB;EACI;;;AAIR;EACI,kBC5Ec;ED6Ed,OC3EW;ED4EX;EACA;EACA;EACA;EACA,QE7FU;EF8FV;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI,kBCzFY;ED0FZ,OC7FU;ED8FV;;AAGJ;EACI,kBChGO;EDiGP,OClGI;EDmGJ;;AACA;EACI,kBCnGQ;;ADuGhB;EACI,kBE7FW;EF8FX;;AAEA;EACI,kBEjGO;EFkGP;;AAIR;EACI;EACA;EACA;EACA;EACA,OErGa;EFsGb,kBErGmB;;AFuGnB;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;;;AAOZ;EACI,kBEnImB;EFoInB,OClJQ;EDmJR,QE/JU;EFgKV;EACA;EACA;;;AAIA;EACI;EACA;EACA;EACA;EE9JN;;AACA;EFyJE;IExJA;IACA;;;AF+JA;EElKF;;AACA;EFiKE;IEhKA;IACA;;;;AFsKA;EACI;EACA;;AAGJ;EACI;EACA;;AAEA;EACI,WE5LE;EF6LF;;AAGJ;EACI;EACA;EACA;EACA,OE/KC;;;AFqLT;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIR;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA,OCpOA;;ADwOR;EACI,OE7NK;EF8NL;EACA;EACA;;AAEA;EACI;EACA;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA,OCnQI;EDoQJ;EACA;EACA;EACA;;AAEA;EACI;EACA,kBE7PW;;AFgQf;EACI;;AAIR;EACI;;AAKA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA,cEtRO;EFuRP;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;AAKR;EACI;;AAEA;EACI;;AAEA;EACI;;AAEJ;EACI,OElTP;;AFyTL;EACI;;AAEJ;EACI;EACA;EACA;EACA;EE5UV;;AACA;EFuUM;IEtUJ;IACA;;;AF8UQ;EACI;EACA;EEnVd;;AACA;EFgVU;IE/UR;IACA;;;AFqVI;EACI;EACA;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA,OE1VN;;AF+VE;EACI,OEjWL;;AFsWP;EACI;;AACA;EACI;EACA;;;AAKZ;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI,MC7YI;;ADgZR;EACI,MClZU;;;ADuZd;EACI;EACA;;;AAIR;EAEQ;EAEJ;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;AAAkB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;AACA;EACA;AAEA;EACA;AAEA;EACA;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI,OEjbO;;;AFobX;EACI;;;AAGJ;EACI;;;AG9dJ;EACI,kBFeQ;EEdR,OFac;;AERd;EACI;;AAGJ;EACI,OFGU;;AEAd;EACI;EACA;EACA;;AAEA;EACI,kBFIa;EEHb;EACA,ODyBgB;;ACtBpB;EACI,kBFVG;EEWH,ODoBgB;ECnBhB;EACA;;AACA;EACI,kBFdI;;AEkBZ;EACI,kBDRO;ECSP;;AAEA;EACI,kBDZG;ECaH;;AAIR;EACI,OFhCM;;AEkCN;EACI;EACA,kBDHY;;ACQhB;EDxCV;;AACA;ECuCU;IDtCR;IACA;;;ACyCQ;EACI,kBDbY;;ACeZ;ED/Cd;;AACA;EC8Cc;ID7CZ;IACA;;;ACmDQ;EDtDV;;AACA;ECqDU;IDpDR;IACA;;;ACwDY;ED3Dd;;AACA;EC0Dc;IDzDZ;IACA;;;AC8DI;EACI,OD7Bc;EC8Bd,kBD7BoB;;AC+BpB;EACI;;AAKZ;EACI,kBD5CoB;EC6CpB,OF9EU;;AEkFV;EACI,MFnFM;;AEsFV;EACI,MFtFA;;AE0FR;EAEQ;;;AAMR;EACI,OFpGU;;AEwGb;EACI,ODhEM;;ACoEN;EACI,ODtEG;;;AC8EZ;EDrHF;;AACA;ECoHE;IDnHA;IACA;;;ACsHA;EDzHF;;AACA;ECwHE;IDvHA;IACA;;;;AC2HJ;EACI;;;AAGJ;EACI,OD5FY","file":"light.css"}
|
@ -5,10 +5,15 @@
|
||||
font-family: $standardFont;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0 0 100px 0;
|
||||
|
||||
&.waiting * {
|
||||
cursor: wait !important;
|
||||
}
|
||||
}
|
||||
|
||||
html {
|
||||
|
@ -75,11 +75,15 @@
|
||||
font-family: Lato;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0 0 100px 0;
|
||||
}
|
||||
body.waiting * {
|
||||
cursor: wait !important;
|
||||
}
|
||||
|
||||
html {
|
||||
width: 100%;
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/fonts.scss","../../scss/main.scss","../../scss/variables.scss"],"names":[],"mappings":"AACA;EACI;EACA;;AAIJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;AAA6D;EAC7D;;AC5EJ;EACI;EACA,aCHW;EDIX;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;EACA,kBCQc;EDPd,OCQQ;EDPR;EACA;EACA;EAEI;;;AAIR;EACI,OCFQ;EDGR,aC3BS;ED4BT;EACA,WCzBS;ED0BT;;;AAGJ;EACI,OCVQ;EDWR,aCnCS;EDoCT;EACA,WChCU;;;ADmCd;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AAIR;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;;;AAGJ;EACI,OC9CW;ED+CX;EACA;;AAEA;EACI,OClDY;;ADqDhB;EACI;;;AAIR;EACI,kBC9Dc;ED+Dd,OC7DW;ED8DX;EACA;EACA;EACA;EACA,QCxFU;EDyFV;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI,kBC3EY;ED4EZ,OC/EU;EDgFV;;AAGJ;EACI,kBClFO;EDmFP,OCpFI;EDqFJ;;AACA;EACI,kBCrFQ;;ADyFhB;EACI,kBCxFW;EDyFX;;AAEA;EACI,kBC5FO;ED6FP;;AAIR;EACI;EACA;EACA;EACA;EACA,OChGa;EDiGb,kBChGmB;;ADkGnB;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;;;AAOZ;EACI,kBC9HmB;ED+HnB,OCpIQ;EDqIR,QC1JU;ED2JV;EACA;EACA;;;AAIA;EACI;EACA;EACA;EACA;ECzJN;;AACA;EDoJE;ICnJA;IACA;;;AD0JA;EC7JF;;AACA;ED4JE;IC3JA;IACA;;;;ADiKA;EACI;EACA;;AAGJ;EACI;EACA;;AAEA;EACI,WCvLE;EDwLF;;AAGJ;EACI;EACA;EACA;EACA,OC1KC;;;ADgLT;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIR;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA,OCtNA;;AD0NR;EACI,OCxNK;EDyNL;EACA;EACA;;AAEA;EACI;EACA;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA,OCrPI;EDsPJ;EACA;EACA;EACA;;AAEA;EACI;EACA,kBCxPW;;AD2Pf;EACI;;AAIR;EACI;;AAKA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA,cCjRO;EDkRP;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;AAKR;EACI;;AAEA;EACI;;AAEA;EACI;;AAEJ;EACI,OC7SP;;ADoTL;EACI;;AAEJ;EACI;EACA;EACA;EACA;ECvUV;;AACA;EDkUM;ICjUJ;IACA;;;ADyUQ;EACI;EACA;EC9Ud;;AACA;ED2UU;IC1UR;IACA;;;ADgVI;EACI;EACA;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA,OCrVN;;AD0VE;EACI,OC5VL;;ADiWP;EACI;;AACA;EACI;EACA;;;AAKZ;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI,MC/XI;;ADkYR;EACI,MCpYU;;;ADyYd;EACI;EACA;;;AAIR;EAII;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;AAAkB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;AACA;EACA;AAEA;EACA;AAEA;EACA;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI,OC5aO;;;AD+aX;EACI;;;AAGJ;EACI","file":"dark.css"}
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/fonts.scss","../../scss/main.scss","../../scss/variables.scss"],"names":[],"mappings":"AACA;EACI;EACA;;AAIJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;AAA6D;EAC7D;;AC5EJ;EACI;EACA,aCHW;EDIX;EACA;EACA;;;AAGJ;EACI;;AAEA;EACI;;;AAIR;EACI;EACA;EACA;EACA,kBCGc;EDFd,OCGQ;EDFR;EACA;EACA;EAEI;;;AAIR;EACI,OCPQ;EDQR,aChCS;EDiCT;EACA,WC9BS;ED+BT;;;AAGJ;EACI,OCfQ;EDgBR,aCxCS;EDyCT;EACA,WCrCU;;;ADwCd;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AAIR;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;;;AAGJ;EACI,OCnDW;EDoDX;EACA;;AAEA;EACI,OCvDY;;AD0DhB;EACI;;;AAIR;EACI,kBCnEc;EDoEd,OClEW;EDmEX;EACA;EACA;EACA;EACA,QC7FU;ED8FV;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI,kBChFY;EDiFZ,OCpFU;EDqFV;;AAGJ;EACI,kBCvFO;EDwFP,OCzFI;ED0FJ;;AACA;EACI,kBC1FQ;;AD8FhB;EACI,kBC7FW;ED8FX;;AAEA;EACI,kBCjGO;EDkGP;;AAIR;EACI;EACA;EACA;EACA;EACA,OCrGa;EDsGb,kBCrGmB;;ADuGnB;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;;;AAOZ;EACI,kBCnImB;EDoInB,OCzIQ;ED0IR,QC/JU;EDgKV;EACA;EACA;;;AAIA;EACI;EACA;EACA;EACA;EC9JN;;AACA;EDyJE;ICxJA;IACA;;;AD+JA;EClKF;;AACA;EDiKE;IChKA;IACA;;;;ADsKA;EACI;EACA;;AAGJ;EACI;EACA;;AAEA;EACI,WC5LE;ED6LF;;AAGJ;EACI;EACA;EACA;EACA,OC/KC;;;ADqLT;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIR;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA,OC3NA;;AD+NR;EACI,OC7NK;ED8NL;EACA;EACA;;AAEA;EACI;EACA;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA,OC1PI;ED2PJ;EACA;EACA;EACA;;AAEA;EACI;EACA,kBC7PW;;ADgQf;EACI;;AAIR;EACI;;AAKA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA,cCtRO;EDuRP;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;AAKR;EACI;;AAEA;EACI;;AAEA;EACI;;AAEJ;EACI,OClTP;;ADyTL;EACI;;AAEJ;EACI;EACA;EACA;EACA;EC5UV;;AACA;EDuUM;ICtUJ;IACA;;;AD8UQ;EACI;EACA;ECnVd;;AACA;EDgVU;IC/UR;IACA;;;ADqVI;EACI;EACA;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA,OC1VN;;AD+VE;EACI,OCjWL;;ADsWP;EACI;;AACA;EACI;EACA;;;AAKZ;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI,MCpYI;;ADuYR;EACI,MCzYU;;;AD8Yd;EACI;EACA;;;AAIR;EAII;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;AAAkB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;AACA;EACA;AAEA;EACA;AAEA;EACA;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI,OCjbO;;;ADobX;EACI;;;AAGJ;EACI","file":"dark.css"}
|
@ -75,11 +75,15 @@
|
||||
font-family: Lato;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0 0 100px 0;
|
||||
}
|
||||
body.waiting * {
|
||||
cursor: wait !important;
|
||||
}
|
||||
|
||||
html {
|
||||
width: 100%;
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/fonts.scss","../../scss/main.scss","../../scss/variables.scss","../../scss/light.scss"],"names":[],"mappings":"AACA;EACI;EACA;;AAIJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;AAA6D;EAC7D;;AC5EJ;EACI;EACA,aCHW;EDIX;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;EACA,kBCQc;EDPd,OCQQ;EDPR;EACA;EACA;EAEI;;;AAIR;EACI,OCFQ;EDGR,aC3BS;ED4BT;EACA,WCzBS;ED0BT;;;AAGJ;EACI,OCVQ;EDWR,aCnCS;EDoCT;EACA,WChCU;;;ADmCd;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AAIR;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;;;AAGJ;EACI,OC9CW;ED+CX;EACA;;AAEA;EACI,OClDY;;ADqDhB;EACI;;;AAIR;EACI,kBC9Dc;ED+Dd,OC7DW;ED8DX;EACA;EACA;EACA;EACA,QCxFU;EDyFV;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI,kBC3EY;ED4EZ,OC/EU;EDgFV;;AAGJ;EACI,kBClFO;EDmFP,OCpFI;EDqFJ;;AACA;EACI,kBCrFQ;;ADyFhB;EACI,kBCxFW;EDyFX;;AAEA;EACI,kBC5FO;ED6FP;;AAIR;EACI;EACA;EACA;EACA;EACA,OChGa;EDiGb,kBChGmB;;ADkGnB;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;;;AAOZ;EACI,kBC9HmB;ED+HnB,OCpIQ;EDqIR,QC1JU;ED2JV;EACA;EACA;;;AAIA;EACI;EACA;EACA;EACA;ECzJN;;AACA;EDoJE;ICnJA;IACA;;;AD0JA;EC7JF;;AACA;ED4JE;IC3JA;IACA;;;;ADiKA;EACI;EACA;;AAGJ;EACI;EACA;;AAEA;EACI,WCvLE;EDwLF;;AAGJ;EACI;EACA;EACA;EACA,OC1KC;;;ADgLT;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIR;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA,OCtNA;;AD0NR;EACI,OCxNK;EDyNL;EACA;EACA;;AAEA;EACI;EACA;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA,OCrPI;EDsPJ;EACA;EACA;EACA;;AAEA;EACI;EACA,kBCxPW;;AD2Pf;EACI;;AAIR;EACI;;AAKA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA,cCjRO;EDkRP;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;AAKR;EACI;;AAEA;EACI;;AAEA;EACI;;AAEJ;EACI,OC7SP;;ADoTL;EACI;;AAEJ;EACI;EACA;EACA;EACA;ECvUV;;AACA;EDkUM;ICjUJ;IACA;;;ADyUQ;EACI;EACA;EC9Ud;;AACA;ED2UU;IC1UR;IACA;;;ADgVI;EACI;EACA;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA,OCrVN;;AD0VE;EACI,OC5VL;;ADiWP;EACI;;AACA;EACI;EACA;;;AAKZ;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI,MC/XI;;ADkYR;EACI,MCpYU;;;ADyYd;EACI;EACA;;;AAIR;EAII;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;AAAkB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;AACA;EACA;AAEA;EACA;AAEA;EACA;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI,OC5aO;;;AD+aX;EACI;;;AAGJ;EACI;;;AEzdJ;EACI,kBD2CmB;EC1CnB,ODsBc;ECpBV;;AAGJ;EACI;;AAGJ;EACI,ODYU;;ACTd;EACI,kBD4Be;EC3Bf,ODSO;ECRP;;AAEA;EACI,kBD0Ba;ECzBb;EACA,ODyBgB;;ACtBpB;EACI,kBDDG;ECEH,ODoBgB;ECnBhB;EACA;;AACA;EACI,kBDLI;;ACSZ;EACI,kBDRO;ECSP;;AAEA;EACI,kBDZG;ECaH;;AAIR;EACI,ODvBM;;ACyBN;EACI;EACA,kBDHY;;ACQhB;EDxCV;;AACA;ECuCU;IDtCR;IACA;;;ACyCQ;EACI,kBDbY;;ACeZ;ED/Cd;;AACA;EC8Cc;ID7CZ;IACA;;;ACmDQ;EDtDV;;AACA;ECqDU;IDpDR;IACA;;;ACwDY;ED3Dd;;AACA;EC0Dc;IDzDZ;IACA;;;AC8DI;EACI,OD7Bc;EC8Bd,kBD7BoB;;AC+BpB;EACI;;AAKZ;EACI,kBD5CoB;EC6CpB,ODrEU;;ACyEV;EACI,MD1EM;;AC6EV;EACI,MD1DW;;ACsEnB;EACI,OD3FU;;AC+Fb;EACI,ODhEM;;ACoEN;EACI,ODtEG;;;AC8EZ;EDrHF;;AACA;ECoHE;IDnHA;IACA;;;ACsHA;EDzHF;;AACA;ECwHE;IDvHA;IACA;;;;AC2HJ;EACI;;;AAGJ;EACI,OD5FY","file":"light.css"}
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/fonts.scss","../../scss/main.scss","../../scss/variables.scss","../../scss/light.scss"],"names":[],"mappings":"AACA;EACI;EACA;;AAIJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;AAA6D;EAC7D;;AC5EJ;EACI;EACA,aCHW;EDIX;EACA;EACA;;;AAGJ;EACI;;AAEA;EACI;;;AAIR;EACI;EACA;EACA;EACA,kBCGc;EDFd,OCGQ;EDFR;EACA;EACA;EAEI;;;AAIR;EACI,OCPQ;EDQR,aChCS;EDiCT;EACA,WC9BS;ED+BT;;;AAGJ;EACI,OCfQ;EDgBR,aCxCS;EDyCT;EACA,WCrCU;;;ADwCd;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AAIR;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;;;AAGJ;EACI,OCnDW;EDoDX;EACA;;AAEA;EACI,OCvDY;;AD0DhB;EACI;;;AAIR;EACI,kBCnEc;EDoEd,OClEW;EDmEX;EACA;EACA;EACA;EACA,QC7FU;ED8FV;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI,kBChFY;EDiFZ,OCpFU;EDqFV;;AAGJ;EACI,kBCvFO;EDwFP,OCzFI;ED0FJ;;AACA;EACI,kBC1FQ;;AD8FhB;EACI,kBC7FW;ED8FX;;AAEA;EACI,kBCjGO;EDkGP;;AAIR;EACI;EACA;EACA;EACA;EACA,OCrGa;EDsGb,kBCrGmB;;ADuGnB;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;;;AAOZ;EACI,kBCnImB;EDoInB,OCzIQ;ED0IR,QC/JU;EDgKV;EACA;EACA;;;AAIA;EACI;EACA;EACA;EACA;EC9JN;;AACA;EDyJE;ICxJA;IACA;;;AD+JA;EClKF;;AACA;EDiKE;IChKA;IACA;;;;ADsKA;EACI;EACA;;AAGJ;EACI;EACA;;AAEA;EACI,WC5LE;ED6LF;;AAGJ;EACI;EACA;EACA;EACA,OC/KC;;;ADqLT;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIR;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA,OC3NA;;AD+NR;EACI,OC7NK;ED8NL;EACA;EACA;;AAEA;EACI;EACA;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA,OC1PI;ED2PJ;EACA;EACA;EACA;;AAEA;EACI;EACA,kBC7PW;;ADgQf;EACI;;AAIR;EACI;;AAKA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA,cCtRO;EDuRP;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;AAKR;EACI;;AAEA;EACI;;AAEA;EACI;;AAEJ;EACI,OClTP;;ADyTL;EACI;;AAEJ;EACI;EACA;EACA;EACA;EC5UV;;AACA;EDuUM;ICtUJ;IACA;;;AD8UQ;EACI;EACA;ECnVd;;AACA;EDgVU;IC/UR;IACA;;;ADqVI;EACI;EACA;;AAIR;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA,OC1VN;;AD+VE;EACI,OCjWL;;ADsWP;EACI;;AACA;EACI;EACA;;;AAKZ;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI,MCpYI;;ADuYR;EACI,MCzYU;;;AD8Yd;EACI;EACA;;;AAIR;EAII;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;AAAkB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;AACA;EACA;AAEA;EACA;AAEA;EACA;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI,OCjbO;;;ADobX;EACI;;;AAGJ;EACI;;;AE9dJ;EACI,kBD2CmB;EC1CnB,ODsBc;ECpBV;;AAGJ;EACI;;AAGJ;EACI,ODYU;;ACTd;EACI,kBD4Be;EC3Bf,ODSO;ECRP;;AAEA;EACI,kBD0Ba;ECzBb;EACA,ODyBgB;;ACtBpB;EACI,kBDDG;ECEH,ODoBgB;ECnBhB;EACA;;AACA;EACI,kBDLI;;ACSZ;EACI,kBDRO;ECSP;;AAEA;EACI,kBDZG;ECaH;;AAIR;EACI,ODvBM;;ACyBN;EACI;EACA,kBDHY;;ACQhB;EDxCV;;AACA;ECuCU;IDtCR;IACA;;;ACyCQ;EACI,kBDbY;;ACeZ;ED/Cd;;AACA;EC8Cc;ID7CZ;IACA;;;ACmDQ;EDtDV;;AACA;ECqDU;IDpDR;IACA;;;ACwDY;ED3Dd;;AACA;EC0Dc;IDzDZ;IACA;;;AC8DI;EACI,OD7Bc;EC8Bd,kBD7BoB;;AC+BpB;EACI;;AAKZ;EACI,kBD5CoB;EC6CpB,ODrEU;;ACyEV;EACI,MD1EM;;AC6EV;EACI,MD1DW;;ACsEnB;EACI,OD3FU;;AC+Fb;EACI,ODhEM;;ACoEN;EACI,ODtEG;;;AC8EZ;EDrHF;;AACA;ECoHE;IDnHA;IACA;;;ACsHA;EDzHF;;AACA;ECwHE;IDvHA;IACA;;;;AC2HJ;EACI;;;AAGJ;EACI,OD5FY","file":"light.css"}
|
@ -15,9 +15,6 @@
|
||||
|
||||
<div class="actions">
|
||||
<button class="primary right" type="submit">{{t "Actions.Next"}}</button>
|
||||
<a class="button secondary" href="{{ loginUrl }}">
|
||||
{{t "Actions.Cancel"}}
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
@ -30,7 +30,9 @@
|
||||
{{ template "error-message" .}}
|
||||
|
||||
<div class="actions">
|
||||
<button class="secondary right wa-support" id="submit-button" type="submit" name="recreate" value="true">{{t "Actions.Recreate"}}</button>
|
||||
<a class="button secondary" href="{{ mfaPromptChangeUrl .AuthReqID .MFAType }}">
|
||||
{{t "Actions.Back"}}
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
{{end}}
|
||||
|
||||
<div class="actions">
|
||||
<button class="primary right" id="submit-button" type="submit">{{t "Actions.Next"}}</button>
|
||||
<button class="primary" id="submit-button" type="submit">{{t "Actions.Next"}}</button>
|
||||
<a class="button secondary" href="{{ mfaPromptChangeUrl .AuthReqID .MFAType }}">
|
||||
{{t "Actions.Back"}}
|
||||
</a>
|
||||
|
@ -26,7 +26,15 @@
|
||||
{{ template "error-message" .}}
|
||||
|
||||
<div class="actions">
|
||||
<button class="secondary right wa-support" id="submit-button" type="submit" name="recreate" value="true">{{t "Actions.Recreate"}}</button>
|
||||
{{ if .MFAProviders }}
|
||||
<div class="mfa-other">
|
||||
<p>{{t "MFA.ChooseOther"}}</p>
|
||||
{{ range $provider := .MFAProviders}}
|
||||
{{ $providerName := (t (printf "MFA.Provider%v" $provider)) }}
|
||||
<button class="secondary" type="submit" name="provider" value="{{$provider}}">{{$providerName}}</button>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
@ -23,7 +23,16 @@
|
||||
{{ template "error-message" .}}
|
||||
|
||||
<div class="actions">
|
||||
<button class="primary right" id="submit-button" type="submit">{{t "Actions.Next"}}</button>
|
||||
<button class="primary" id="submit-button" type="submit">{{t "Actions.Next"}}</button>
|
||||
{{ if .MFAProviders }}
|
||||
<div class="mfa-other">
|
||||
<p>{{t "MFA.ChooseOther"}}</p>
|
||||
{{ range $provider := .MFAProviders}}
|
||||
{{ $providerName := (t (printf "MFA.Provider%v" $provider)) }}
|
||||
<button class="secondary" type="submit" name="provider" value="{{$provider}}" formnovalidate>{{$providerName}}</button>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
<a class="button secondary" href="{{ loginUrl }}">
|
||||
{{t "Actions.Cancel"}}
|
||||
</a>
|
||||
|
@ -26,7 +26,9 @@
|
||||
{{ template "error-message" .}}
|
||||
|
||||
<div class="actions">
|
||||
<button class="secondary right wa-support" id="submit-button" type="submit" name="recreate" value="true">{{t "Actions.Recreate"}}</button>
|
||||
<a href="{{ loginNameChangeUrl .AuthReqID }}">
|
||||
<button class="secondary" type="button">{{t "Actions.Back"}}</button>
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
@ -26,6 +26,7 @@ type MultiFactor struct {
|
||||
Type MFAType
|
||||
State MFAState
|
||||
Attribute string
|
||||
ID string
|
||||
}
|
||||
|
||||
type MFAType int32
|
||||
|
@ -70,7 +70,7 @@ func StartUser(conf UserConfig, systemDefaults sd.SystemDefaults) (*UserEventsto
|
||||
passwordVerificationCode := crypto.NewEncryptionGenerator(systemDefaults.SecretGenerators.PasswordVerificationCode, aesCrypto)
|
||||
aesOTPCrypto, err := crypto.NewAESCrypto(systemDefaults.Multifactors.OTP.VerificationKey)
|
||||
passwordAlg := crypto.NewBCrypt(systemDefaults.SecretGenerators.PasswordSaltCost)
|
||||
web, err := webauthn_helper.StartServer(systemDefaults.WebAuthN.DisplayName, systemDefaults.WebAuthN.ID, systemDefaults.WebAuthN.Origin)
|
||||
web, err := webauthn_helper.StartServer(systemDefaults.WebAuthN)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -578,10 +578,10 @@ func (es *UserEventstore) SetOneTimePassword(ctx context.Context, policy *iam_mo
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return es.changedPassword(ctx, user, policy, password.SecretString, true)
|
||||
return es.changedPassword(ctx, user, policy, password.SecretString, true, "")
|
||||
}
|
||||
|
||||
func (es *UserEventstore) SetPassword(ctx context.Context, policy *iam_model.PasswordComplexityPolicyView, userID, code, password string) error {
|
||||
func (es *UserEventstore) SetPassword(ctx context.Context, policy *iam_model.PasswordComplexityPolicyView, userID, code, password, userAgentID string) error {
|
||||
user, err := es.HumanByID(ctx, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -592,7 +592,7 @@ func (es *UserEventstore) SetPassword(ctx context.Context, policy *iam_model.Pas
|
||||
if err := crypto.VerifyCode(user.PasswordCode.CreationDate, user.PasswordCode.Expiry, user.PasswordCode.Code, code, es.PasswordVerificationCode); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = es.changedPassword(ctx, user, policy, password, false)
|
||||
_, err = es.changedPassword(ctx, user, policy, password, false, userAgentID)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -655,7 +655,7 @@ func (es *UserEventstore) ChangeMachine(ctx context.Context, machine *usr_model.
|
||||
return model.MachineToModel(repoUser.Machine), nil
|
||||
}
|
||||
|
||||
func (es *UserEventstore) ChangePassword(ctx context.Context, policy *iam_model.PasswordComplexityPolicyView, userID, old, new string) (_ *usr_model.Password, err error) {
|
||||
func (es *UserEventstore) ChangePassword(ctx context.Context, policy *iam_model.PasswordComplexityPolicyView, userID, old, new, userAgentID string) (_ *usr_model.Password, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
@ -672,10 +672,10 @@ func (es *UserEventstore) ChangePassword(ctx context.Context, policy *iam_model.
|
||||
if err != nil {
|
||||
return nil, caos_errs.ThrowInvalidArgument(nil, "EVENT-s56a3", "Errors.User.Password.Invalid")
|
||||
}
|
||||
return es.changedPassword(ctx, user, policy, new, false)
|
||||
return es.changedPassword(ctx, user, policy, new, false, userAgentID)
|
||||
}
|
||||
|
||||
func (es *UserEventstore) changedPassword(ctx context.Context, user *usr_model.User, policy *iam_model.PasswordComplexityPolicyView, password string, onetime bool) (_ *usr_model.Password, err error) {
|
||||
func (es *UserEventstore) changedPassword(ctx context.Context, user *usr_model.User, policy *iam_model.PasswordComplexityPolicyView, password string, onetime bool, userAgentID string) (_ *usr_model.Password, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
pw := &usr_model.Password{SecretString: password}
|
||||
@ -683,7 +683,7 @@ func (es *UserEventstore) changedPassword(ctx context.Context, user *usr_model.U
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
repoPassword := model.PasswordFromModel(pw)
|
||||
repoPassword := model.PasswordChangeFromModel(pw, userAgentID)
|
||||
repoUser := model.UserFromModel(user)
|
||||
agg := PasswordChangeAggregate(es.AggregateCreator(), repoUser, repoPassword)
|
||||
err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, agg)
|
||||
@ -1235,7 +1235,7 @@ func (es *UserEventstore) RemoveOTP(ctx context.Context, userID string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (es *UserEventstore) CheckMFAOTPSetup(ctx context.Context, userID, code string) error {
|
||||
func (es *UserEventstore) CheckMFAOTPSetup(ctx context.Context, userID, code, userAgentID string) error {
|
||||
user, err := es.HumanByID(ctx, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -1250,7 +1250,7 @@ func (es *UserEventstore) CheckMFAOTPSetup(ctx context.Context, userID, code str
|
||||
return err
|
||||
}
|
||||
repoUser := model.UserFromModel(user)
|
||||
err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, MFAOTPVerifyAggregate(es.AggregateCreator(), repoUser))
|
||||
err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, MFAOTPVerifyAggregate(es.AggregateCreator(), repoUser, userAgentID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1302,12 +1302,12 @@ func (es *UserEventstore) verifyMFAOTP(otp *usr_model.OTP, code string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (es *UserEventstore) AddU2F(ctx context.Context, userID string) (*usr_model.WebAuthNToken, error) {
|
||||
func (es *UserEventstore) AddU2F(ctx context.Context, userID string, isLoginUI bool) (*usr_model.WebAuthNToken, error) {
|
||||
user, err := es.HumanByID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
webAuthN, err := es.webauthn.BeginRegistration(user, usr_model.AuthenticatorAttachmentUnspecified, usr_model.UserVerificationRequirementDiscouraged, user.U2FTokens...)
|
||||
webAuthN, err := es.webauthn.BeginRegistration(user, usr_model.AuthenticatorAttachmentUnspecified, usr_model.UserVerificationRequirementDiscouraged, isLoginUI, user.U2FTokens...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1316,6 +1316,7 @@ func (es *UserEventstore) AddU2F(ctx context.Context, userID string) (*usr_model
|
||||
return nil, err
|
||||
}
|
||||
webAuthN.WebAuthNTokenID = tokenID
|
||||
webAuthN.State = usr_model.MFAStateNotReady
|
||||
repoUser := model.UserFromModel(user)
|
||||
repoWebAuthN := model.WebAuthNFromModel(webAuthN)
|
||||
|
||||
@ -1326,18 +1327,18 @@ func (es *UserEventstore) AddU2F(ctx context.Context, userID string) (*usr_model
|
||||
return webAuthN, nil
|
||||
}
|
||||
|
||||
func (es *UserEventstore) VerifyU2FSetup(ctx context.Context, userID, tokenName string, credentialData []byte) error {
|
||||
func (es *UserEventstore) VerifyU2FSetup(ctx context.Context, userID, tokenName, userAgentID string, credentialData []byte) error {
|
||||
user, err := es.HumanByID(ctx, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, token := user.Human.GetU2FToVerify()
|
||||
webAuthN, err := es.webauthn.FinishRegistration(user, token, tokenName, credentialData)
|
||||
webAuthN, err := es.webauthn.FinishRegistration(user, token, tokenName, credentialData, userAgentID != "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
repoUser := model.UserFromModel(user)
|
||||
repoWebAuthN := model.WebAuthNVerifyFromModel(webAuthN)
|
||||
repoWebAuthN := model.WebAuthNVerifyFromModel(webAuthN, userAgentID)
|
||||
err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, MFAU2FVerifyAggregate(es.AggregateCreator(), repoUser, repoWebAuthN))
|
||||
if err != nil {
|
||||
return err
|
||||
@ -1363,7 +1364,7 @@ func (es *UserEventstore) RemoveU2FToken(ctx context.Context, userID, webAuthNTo
|
||||
return nil
|
||||
}
|
||||
|
||||
func (es *UserEventstore) BeginU2FLogin(ctx context.Context, userID string, authRequest *req_model.AuthRequest) (*usr_model.WebAuthNLogin, error) {
|
||||
func (es *UserEventstore) BeginU2FLogin(ctx context.Context, userID string, authRequest *req_model.AuthRequest, isLoginUI bool) (*usr_model.WebAuthNLogin, error) {
|
||||
user, err := es.HumanByID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -1372,7 +1373,7 @@ func (es *UserEventstore) BeginU2FLogin(ctx context.Context, userID string, auth
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-5Mk8s", "Errors.User.MFA.U2F.NotExisting")
|
||||
}
|
||||
|
||||
webAuthNLogin, err := es.webauthn.BeginLogin(user, usr_model.UserVerificationRequirementDiscouraged, user.U2FTokens...)
|
||||
webAuthNLogin, err := es.webauthn.BeginLogin(user, usr_model.UserVerificationRequirementDiscouraged, isLoginUI, user.U2FTokens...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1386,13 +1387,13 @@ func (es *UserEventstore) BeginU2FLogin(ctx context.Context, userID string, auth
|
||||
return webAuthNLogin, nil
|
||||
}
|
||||
|
||||
func (es *UserEventstore) VerifyMFAU2F(ctx context.Context, userID string, credentialData []byte, authRequest *req_model.AuthRequest) error {
|
||||
func (es *UserEventstore) VerifyMFAU2F(ctx context.Context, userID string, credentialData []byte, authRequest *req_model.AuthRequest, isLoginUI bool) error {
|
||||
user, err := es.HumanByID(ctx, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, u2f := user.GetU2FLogin(authRequest.ID)
|
||||
keyID, signCount, finishErr := es.webauthn.FinishLogin(user, u2f, credentialData, user.U2FTokens...)
|
||||
keyID, signCount, finishErr := es.webauthn.FinishLogin(user, u2f, credentialData, isLoginUI, user.U2FTokens...)
|
||||
if finishErr != nil && keyID == nil {
|
||||
return finishErr
|
||||
}
|
||||
@ -1409,12 +1410,12 @@ func (es *UserEventstore) VerifyMFAU2F(ctx context.Context, userID string, crede
|
||||
return finishErr
|
||||
}
|
||||
|
||||
func (es *UserEventstore) AddPasswordless(ctx context.Context, userID string) (*usr_model.WebAuthNToken, error) {
|
||||
func (es *UserEventstore) AddPasswordless(ctx context.Context, userID string, isLoginUI bool) (*usr_model.WebAuthNToken, error) {
|
||||
user, err := es.HumanByID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
webAuthN, err := es.webauthn.BeginRegistration(user, usr_model.AuthenticatorAttachmentUnspecified, usr_model.UserVerificationRequirementRequired, user.PasswordlessTokens...)
|
||||
webAuthN, err := es.webauthn.BeginRegistration(user, usr_model.AuthenticatorAttachmentUnspecified, usr_model.UserVerificationRequirementRequired, isLoginUI, user.PasswordlessTokens...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1432,18 +1433,18 @@ func (es *UserEventstore) AddPasswordless(ctx context.Context, userID string) (*
|
||||
return webAuthN, nil
|
||||
}
|
||||
|
||||
func (es *UserEventstore) VerifyPasswordlessSetup(ctx context.Context, userID, tokenName string, credentialData []byte) error {
|
||||
func (es *UserEventstore) VerifyPasswordlessSetup(ctx context.Context, userID, tokenName, userAgentID string, credentialData []byte) error {
|
||||
user, err := es.HumanByID(ctx, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, token := user.Human.GetPasswordlessToVerify()
|
||||
webAuthN, err := es.webauthn.FinishRegistration(user, token, tokenName, credentialData)
|
||||
webAuthN, err := es.webauthn.FinishRegistration(user, token, tokenName, credentialData, userAgentID != "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
repoUser := model.UserFromModel(user)
|
||||
repoWebAuthN := model.WebAuthNVerifyFromModel(webAuthN)
|
||||
repoWebAuthN := model.WebAuthNVerifyFromModel(webAuthN, userAgentID)
|
||||
err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, MFAPasswordlessVerifyAggregate(es.AggregateCreator(), repoUser, repoWebAuthN))
|
||||
if err != nil {
|
||||
return err
|
||||
@ -1469,7 +1470,7 @@ func (es *UserEventstore) RemovePasswordlessToken(ctx context.Context, userID, w
|
||||
return nil
|
||||
}
|
||||
|
||||
func (es *UserEventstore) BeginPasswordlessLogin(ctx context.Context, userID string, authRequest *req_model.AuthRequest) (*usr_model.WebAuthNLogin, error) {
|
||||
func (es *UserEventstore) BeginPasswordlessLogin(ctx context.Context, userID string, authRequest *req_model.AuthRequest, isLoginUI bool) (*usr_model.WebAuthNLogin, error) {
|
||||
user, err := es.HumanByID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -1477,7 +1478,7 @@ func (es *UserEventstore) BeginPasswordlessLogin(ctx context.Context, userID str
|
||||
if user.PasswordlessTokens == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-5M9sd", "Errors.User.MFA.Passwordless.NotExisting")
|
||||
}
|
||||
webAuthNLogin, err := es.webauthn.BeginLogin(user, usr_model.UserVerificationRequirementRequired, user.PasswordlessTokens...)
|
||||
webAuthNLogin, err := es.webauthn.BeginLogin(user, usr_model.UserVerificationRequirementRequired, isLoginUI, user.PasswordlessTokens...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1491,13 +1492,13 @@ func (es *UserEventstore) BeginPasswordlessLogin(ctx context.Context, userID str
|
||||
return webAuthNLogin, nil
|
||||
}
|
||||
|
||||
func (es *UserEventstore) VerifyPasswordless(ctx context.Context, userID string, credentialData []byte, authRequest *req_model.AuthRequest) error {
|
||||
func (es *UserEventstore) VerifyPasswordless(ctx context.Context, userID string, credentialData []byte, authRequest *req_model.AuthRequest, isLoginUI bool) error {
|
||||
user, err := es.HumanByID(ctx, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, passwordless := user.GetPasswordlessLogin(authRequest.ID)
|
||||
keyID, signCount, finishErr := es.webauthn.FinishLogin(user, passwordless, credentialData, user.PasswordlessTokens...)
|
||||
keyID, signCount, finishErr := es.webauthn.FinishLogin(user, passwordless, credentialData, isLoginUI, user.PasswordlessTokens...)
|
||||
if finishErr != nil && keyID == nil {
|
||||
return finishErr
|
||||
}
|
||||
|
@ -1678,7 +1678,7 @@ func TestSetPassword(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := tt.args.es.SetPassword(tt.args.ctx, tt.args.policy, tt.args.userID, tt.args.code, tt.args.password)
|
||||
err := tt.args.es.SetPassword(tt.args.ctx, tt.args.policy, tt.args.userID, tt.args.code, tt.args.password, "")
|
||||
|
||||
if tt.res.errFunc == nil && err != nil {
|
||||
t.Errorf("result has error: %v", err)
|
||||
@ -1838,7 +1838,7 @@ func TestChangePassword(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := tt.args.es.ChangePassword(tt.args.ctx, tt.args.policy, tt.args.userID, tt.args.old, tt.args.new)
|
||||
result, err := tt.args.es.ChangePassword(tt.args.ctx, tt.args.policy, tt.args.userID, tt.args.old, tt.args.new, "")
|
||||
|
||||
if tt.res.errFunc == nil && result.AggregateID == "" {
|
||||
t.Errorf("result has no id")
|
||||
@ -3578,7 +3578,7 @@ func TestCheckMFAOTPSetup(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := tt.args.es.CheckMFAOTPSetup(tt.args.ctx, tt.args.userID, tt.args.code)
|
||||
err := tt.args.es.CheckMFAOTPSetup(tt.args.ctx, tt.args.userID, tt.args.code, "")
|
||||
|
||||
if tt.res.errFunc == nil && err != nil {
|
||||
t.Errorf("result should not get err")
|
||||
|
@ -3,6 +3,7 @@ package model
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
@ -16,6 +17,10 @@ type OTP struct {
|
||||
State int32 `json:"-"`
|
||||
}
|
||||
|
||||
type OTPVerified struct {
|
||||
UserAgentID string `json:"userAgentID,omitempty"`
|
||||
}
|
||||
|
||||
func OTPFromModel(otp *model.OTP) *OTP {
|
||||
return &OTP{
|
||||
ObjectRoot: otp.ObjectRoot,
|
||||
@ -55,3 +60,11 @@ func (o *OTP) setData(event *es_models.Event) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *OTPVerified) SetData(event *es_models.Event) error {
|
||||
if err := json.Unmarshal(event.Data, o); err != nil {
|
||||
logging.Log("EVEN-BF421").WithError(err).Error("could not unmarshal event data")
|
||||
return caos_errs.ThrowInternal(err, "MODEL-GB6hj", "could not unmarshal event")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -26,6 +26,11 @@ type PasswordCode struct {
|
||||
NotificationType int32 `json:"notificationType,omitempty"`
|
||||
}
|
||||
|
||||
type PasswordChange struct {
|
||||
Password
|
||||
UserAgentID string `json:"userAgentID,omitempty"`
|
||||
}
|
||||
|
||||
func PasswordFromModel(password *model.Password) *Password {
|
||||
return &Password{
|
||||
ObjectRoot: password.ObjectRoot,
|
||||
@ -51,6 +56,17 @@ func PasswordCodeToModel(code *PasswordCode) *model.PasswordCode {
|
||||
}
|
||||
}
|
||||
|
||||
func PasswordChangeFromModel(password *model.Password, userAgentID string) *PasswordChange {
|
||||
return &PasswordChange{
|
||||
Password: Password{
|
||||
ObjectRoot: password.ObjectRoot,
|
||||
Secret: password.SecretCrypto,
|
||||
ChangeRequired: password.ChangeRequired,
|
||||
},
|
||||
UserAgentID: userAgentID,
|
||||
}
|
||||
}
|
||||
|
||||
func (u *Human) appendUserPasswordChangedEvent(event *es_models.Event) error {
|
||||
u.Password = new(Password)
|
||||
err := u.Password.setData(event)
|
||||
@ -84,3 +100,12 @@ func (c *PasswordCode) SetData(event *es_models.Event) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pw *PasswordChange) SetData(event *es_models.Event) error {
|
||||
if err := json.Unmarshal(event.Data, pw); err != nil {
|
||||
logging.Log("EVEN-ADs31").WithError(err).Error("could not unmarshal event data")
|
||||
return caos_errs.ThrowInternal(err, "MODEL-BDd32", "could not unmarshal event")
|
||||
}
|
||||
pw.ObjectRoot.AppendEvent(event)
|
||||
return nil
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ type WebAuthNVerify struct {
|
||||
AAGUID []byte `json:"aaguid"`
|
||||
SignCount uint32 `json:"signCount"`
|
||||
WebAuthNTokenName string `json:"webAuthNTokenName"`
|
||||
UserAgentID string `json:"userAgentID,omitempty"`
|
||||
}
|
||||
|
||||
type WebAuthNSignCount struct {
|
||||
@ -104,7 +105,7 @@ func WebAuthNToModel(webAuthN *WebAuthNToken) *model.WebAuthNToken {
|
||||
}
|
||||
}
|
||||
|
||||
func WebAuthNVerifyFromModel(webAuthN *model.WebAuthNToken) *WebAuthNVerify {
|
||||
func WebAuthNVerifyFromModel(webAuthN *model.WebAuthNToken, userAgentID string) *WebAuthNVerify {
|
||||
return &WebAuthNVerify{
|
||||
WebAuthNTokenID: webAuthN.WebAuthNTokenID,
|
||||
KeyID: webAuthN.KeyID,
|
||||
@ -113,6 +114,7 @@ func WebAuthNVerifyFromModel(webAuthN *model.WebAuthNToken) *WebAuthNVerify {
|
||||
SignCount: webAuthN.SignCount,
|
||||
AttestationType: webAuthN.AttestationType,
|
||||
WebAuthNTokenName: webAuthN.WebAuthNTokenName,
|
||||
UserAgentID: userAgentID,
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,6 +150,14 @@ func WebAuthNLoginToModel(webAuthN *WebAuthNLogin) *model.WebAuthNLogin {
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WebAuthNVerify) SetData(event *es_models.Event) error {
|
||||
if err := json.Unmarshal(event.Data, w); err != nil {
|
||||
logging.Log("EVEN-G342rf").WithError(err).Error("could not unmarshal event data")
|
||||
return caos_errs.ThrowInternal(err, "MODEL-B6641", "could not unmarshal event")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *Human) appendU2FAddedEvent(event *es_models.Event) error {
|
||||
webauthn := new(WebAuthNToken)
|
||||
err := webauthn.setData(event)
|
||||
|
@ -410,16 +410,16 @@ func SkipMFAAggregate(aggCreator *es_models.AggregateCreator, user *model.User)
|
||||
}
|
||||
}
|
||||
|
||||
func PasswordChangeAggregate(aggCreator *es_models.AggregateCreator, user *model.User, password *model.Password) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
func PasswordChangeAggregate(aggCreator *es_models.AggregateCreator, user *model.User, passwordChange *model.PasswordChange) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
if password == nil {
|
||||
if passwordChange == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-d9832", "Errors.Internal")
|
||||
}
|
||||
agg, err := UserAggregate(ctx, aggCreator, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return agg.AppendEvent(model.HumanPasswordChanged, password)
|
||||
return agg.AppendEvent(model.HumanPasswordChanged, passwordChange)
|
||||
}
|
||||
}
|
||||
|
||||
@ -737,13 +737,13 @@ func MFAOTPAddAggregate(aggCreator *es_models.AggregateCreator, user *model.User
|
||||
}
|
||||
}
|
||||
|
||||
func MFAOTPVerifyAggregate(aggCreator *es_models.AggregateCreator, user *model.User) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
func MFAOTPVerifyAggregate(aggCreator *es_models.AggregateCreator, user *model.User, userAgentID string) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
agg, err := UserAggregate(ctx, aggCreator, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return agg.AppendEvent(model.HumanMFAOTPVerified, nil)
|
||||
return agg.AppendEvent(model.HumanMFAOTPVerified, &model.OTPVerified{UserAgentID: userAgentID})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1060,10 +1060,10 @@ func TestSkipMFAAggregate(t *testing.T) {
|
||||
|
||||
func TestChangePasswordAggregate(t *testing.T) {
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
user *model.User
|
||||
password *model.Password
|
||||
aggCreator *models.AggregateCreator
|
||||
ctx context.Context
|
||||
user *model.User
|
||||
passwordChange *model.PasswordChange
|
||||
aggCreator *models.AggregateCreator
|
||||
}
|
||||
type res struct {
|
||||
eventLen int
|
||||
@ -1086,8 +1086,8 @@ func TestChangePasswordAggregate(t *testing.T) {
|
||||
Profile: &model.Profile{DisplayName: "DisplayName"},
|
||||
},
|
||||
},
|
||||
password: &model.Password{ChangeRequired: true},
|
||||
aggCreator: models.NewAggregateCreator("Test"),
|
||||
passwordChange: &model.PasswordChange{Password: model.Password{ChangeRequired: true}},
|
||||
aggCreator: models.NewAggregateCreator("Test"),
|
||||
},
|
||||
res: res{
|
||||
eventLen: 1,
|
||||
@ -1113,7 +1113,7 @@ func TestChangePasswordAggregate(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
agg, err := PasswordChangeAggregate(tt.args.aggCreator, tt.args.user, tt.args.password)(tt.args.ctx)
|
||||
agg, err := PasswordChangeAggregate(tt.args.aggCreator, tt.args.user, tt.args.passwordChange)(tt.args.ctx)
|
||||
|
||||
if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen {
|
||||
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))
|
||||
@ -2329,7 +2329,7 @@ func TestOTPVerifyAggregate(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
agg, err := MFAOTPVerifyAggregate(tt.args.aggCreator, tt.args.user)(tt.args.ctx)
|
||||
agg, err := MFAOTPVerifyAggregate(tt.args.aggCreator, tt.args.user, "")(tt.args.ctx)
|
||||
|
||||
if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen {
|
||||
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))
|
||||
|
@ -367,12 +367,13 @@ func (u *UserView) addPasswordlessToken(event *models.Event) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, t := range u.PasswordlessTokens {
|
||||
for i, t := range u.PasswordlessTokens {
|
||||
if t.State == int32(model.MFAStateNotReady) {
|
||||
t = token
|
||||
u.PasswordlessTokens[i].ID = token.ID
|
||||
return nil
|
||||
}
|
||||
}
|
||||
token.State = int32(model.MFAStateNotReady)
|
||||
u.U2FTokens = append(u.U2FTokens, token)
|
||||
return nil
|
||||
}
|
||||
@ -413,12 +414,13 @@ func (u *UserView) addU2FToken(event *models.Event) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, t := range u.U2FTokens {
|
||||
for i, t := range u.U2FTokens {
|
||||
if t.State == int32(model.MFAStateNotReady) {
|
||||
t = token
|
||||
u.U2FTokens[i].ID = token.ID
|
||||
return nil
|
||||
}
|
||||
}
|
||||
token.State = int32(model.MFAStateNotReady)
|
||||
u.U2FTokens = append(u.U2FTokens, token)
|
||||
return nil
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ func UserSessionsToModel(userSessions []*UserSessionView) []*model.UserSessionVi
|
||||
return result
|
||||
}
|
||||
|
||||
func (v *UserSessionView) AppendEvent(event *models.Event) {
|
||||
func (v *UserSessionView) AppendEvent(event *models.Event) error {
|
||||
v.Sequence = event.Sequence
|
||||
v.ChangeDate = event.CreationDate
|
||||
switch event.Type {
|
||||
@ -91,7 +91,10 @@ func (v *UserSessionView) AppendEvent(event *models.Event) {
|
||||
v.State = int32(req_model.UserSessionStateActive)
|
||||
case es_model.HumanExternalLoginCheckSucceeded:
|
||||
data := new(es_model.AuthRequest)
|
||||
data.SetData(event)
|
||||
err := data.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.ExternalLoginVerification = event.CreationDate
|
||||
v.SelectedIDPConfigID = data.SelectedIDPConfigID
|
||||
v.State = int32(req_model.UserSessionStateActive)
|
||||
@ -105,15 +108,31 @@ func (v *UserSessionView) AppendEvent(event *models.Event) {
|
||||
v.PasswordlessVerification = time.Time{}
|
||||
v.MultiFactorVerification = time.Time{}
|
||||
case es_model.UserPasswordCheckFailed,
|
||||
es_model.UserPasswordChanged,
|
||||
es_model.HumanPasswordCheckFailed,
|
||||
es_model.HumanPasswordChanged:
|
||||
es_model.HumanPasswordCheckFailed:
|
||||
v.PasswordVerification = time.Time{}
|
||||
case es_model.UserPasswordChanged,
|
||||
es_model.HumanPasswordChanged:
|
||||
data := new(es_model.PasswordChange)
|
||||
err := data.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if v.UserAgentID != data.UserAgentID {
|
||||
v.PasswordVerification = time.Time{}
|
||||
}
|
||||
case es_model.MFAOTPVerified,
|
||||
es_model.HumanMFAOTPVerified:
|
||||
data := new(es_model.OTPVerified)
|
||||
err := data.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if v.UserAgentID == data.UserAgentID {
|
||||
v.setSecondFactorVerification(event.CreationDate, req_model.MFATypeOTP)
|
||||
}
|
||||
case es_model.MFAOTPCheckSucceeded,
|
||||
es_model.HumanMFAOTPCheckSucceeded:
|
||||
v.SecondFactorVerification = event.CreationDate
|
||||
v.SecondFactorVerificationType = int32(req_model.MFATypeOTP)
|
||||
v.State = int32(req_model.UserSessionStateActive)
|
||||
v.setSecondFactorVerification(event.CreationDate, req_model.MFATypeOTP)
|
||||
case es_model.MFAOTPCheckFailed,
|
||||
es_model.MFAOTPRemoved,
|
||||
es_model.HumanMFAOTPCheckFailed,
|
||||
@ -121,10 +140,17 @@ func (v *UserSessionView) AppendEvent(event *models.Event) {
|
||||
es_model.HumanMFAU2FTokenCheckFailed,
|
||||
es_model.HumanMFAU2FTokenRemoved:
|
||||
v.SecondFactorVerification = time.Time{}
|
||||
case es_model.HumanMFAU2FTokenVerified:
|
||||
data := new(es_model.WebAuthNVerify)
|
||||
err := data.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if v.UserAgentID == data.UserAgentID {
|
||||
v.setSecondFactorVerification(event.CreationDate, req_model.MFATypeU2F)
|
||||
}
|
||||
case es_model.HumanMFAU2FTokenCheckSucceeded:
|
||||
v.SecondFactorVerification = event.CreationDate
|
||||
v.SecondFactorVerificationType = int32(req_model.MFATypeU2F)
|
||||
v.State = int32(req_model.UserSessionStateActive)
|
||||
v.setSecondFactorVerification(event.CreationDate, req_model.MFATypeU2F)
|
||||
case es_model.SignedOut,
|
||||
es_model.HumanSignedOut,
|
||||
es_model.UserLocked,
|
||||
@ -137,4 +163,11 @@ func (v *UserSessionView) AppendEvent(event *models.Event) {
|
||||
v.ExternalLoginVerification = time.Time{}
|
||||
v.SelectedIDPConfigID = ""
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *UserSessionView) setSecondFactorVerification(verificationTime time.Time, mfaType req_model.MFAType) {
|
||||
v.SecondFactorVerification = verificationTime
|
||||
v.SecondFactorVerificationType = int32(mfaType)
|
||||
v.State = int32(req_model.UserSessionStateActive)
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
)
|
||||
@ -59,18 +61,87 @@ func TestAppendEvent(t *testing.T) {
|
||||
{
|
||||
name: "append user password changed event",
|
||||
args: args{
|
||||
event: &es_models.Event{CreationDate: now(), Type: es_model.UserPasswordChanged},
|
||||
userView: &UserSessionView{PasswordVerification: now()},
|
||||
event: &es_models.Event{
|
||||
CreationDate: now(),
|
||||
Type: es_model.UserPasswordChanged,
|
||||
Data: func() []byte {
|
||||
d, _ := json.Marshal(&es_model.Password{
|
||||
Secret: &crypto.CryptoValue{Crypted: []byte("test")},
|
||||
})
|
||||
return d
|
||||
}(),
|
||||
},
|
||||
userView: &UserSessionView{UserAgentID: "id", PasswordVerification: now()},
|
||||
},
|
||||
result: &UserSessionView{ChangeDate: now(), PasswordVerification: time.Time{}},
|
||||
result: &UserSessionView{UserAgentID: "id", ChangeDate: now(), PasswordVerification: time.Time{}},
|
||||
},
|
||||
{
|
||||
name: "append human password changed event",
|
||||
args: args{
|
||||
event: &es_models.Event{CreationDate: now(), Type: es_model.HumanPasswordChanged},
|
||||
userView: &UserSessionView{PasswordVerification: now()},
|
||||
event: &es_models.Event{
|
||||
CreationDate: now(),
|
||||
Type: es_model.HumanPasswordChanged,
|
||||
Data: func() []byte {
|
||||
d, _ := json.Marshal(&es_model.PasswordChange{
|
||||
Password: es_model.Password{
|
||||
Secret: &crypto.CryptoValue{Crypted: []byte("test")},
|
||||
},
|
||||
})
|
||||
return d
|
||||
}(),
|
||||
},
|
||||
userView: &UserSessionView{UserAgentID: "id", PasswordVerification: now()},
|
||||
},
|
||||
result: &UserSessionView{ChangeDate: now(), PasswordVerification: time.Time{}},
|
||||
result: &UserSessionView{UserAgentID: "id", ChangeDate: now(), PasswordVerification: time.Time{}},
|
||||
},
|
||||
{
|
||||
name: "append human password changed event same user agent",
|
||||
args: args{
|
||||
event: &es_models.Event{
|
||||
CreationDate: now(),
|
||||
Type: es_model.HumanPasswordChanged,
|
||||
Data: func() []byte {
|
||||
d, _ := json.Marshal(&es_model.PasswordChange{
|
||||
Password: es_model.Password{
|
||||
Secret: &crypto.CryptoValue{Crypted: []byte("test")},
|
||||
},
|
||||
UserAgentID: "id",
|
||||
})
|
||||
return d
|
||||
}(),
|
||||
},
|
||||
userView: &UserSessionView{UserAgentID: "id", PasswordVerification: now()},
|
||||
},
|
||||
result: &UserSessionView{UserAgentID: "id", ChangeDate: now(), PasswordVerification: now()},
|
||||
},
|
||||
{
|
||||
name: "append user otp verified event",
|
||||
args: args{
|
||||
event: &es_models.Event{
|
||||
CreationDate: now(),
|
||||
Type: es_model.MFAOTPVerified,
|
||||
Data: nil,
|
||||
},
|
||||
userView: &UserSessionView{UserAgentID: "id"},
|
||||
},
|
||||
result: &UserSessionView{UserAgentID: "id", ChangeDate: now()},
|
||||
},
|
||||
{
|
||||
name: "append user otp verified event same user agent",
|
||||
args: args{
|
||||
event: &es_models.Event{
|
||||
CreationDate: now(),
|
||||
Type: es_model.MFAOTPVerified,
|
||||
Data: func() []byte {
|
||||
d, _ := json.Marshal(&es_model.OTPVerified{
|
||||
UserAgentID: "id",
|
||||
})
|
||||
return d
|
||||
}(),
|
||||
},
|
||||
userView: &UserSessionView{UserAgentID: "id"},
|
||||
},
|
||||
result: &UserSessionView{UserAgentID: "id", ChangeDate: now(), SecondFactorVerification: now()},
|
||||
},
|
||||
{
|
||||
name: "append user otp check succeeded event",
|
||||
|
@ -7,25 +7,36 @@ import (
|
||||
"github.com/duo-labs/webauthn/protocol"
|
||||
"github.com/duo-labs/webauthn/webauthn"
|
||||
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
)
|
||||
|
||||
type WebAuthN struct {
|
||||
web *webauthn.WebAuthn
|
||||
webLogin *webauthn.WebAuthn
|
||||
webConsole *webauthn.WebAuthn
|
||||
}
|
||||
|
||||
func StartServer(displayName, id, origin string) (*WebAuthN, error) {
|
||||
web, err := webauthn.New(&webauthn.Config{
|
||||
RPDisplayName: displayName,
|
||||
RPID: id,
|
||||
RPOrigin: origin,
|
||||
func StartServer(sd systemdefaults.WebAuthN) (*WebAuthN, error) {
|
||||
webLogin, err := webauthn.New(&webauthn.Config{
|
||||
RPDisplayName: sd.DisplayName,
|
||||
RPID: sd.ID,
|
||||
RPOrigin: sd.OriginLogin,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
webConsole, err := webauthn.New(&webauthn.Config{
|
||||
RPDisplayName: sd.DisplayName,
|
||||
RPID: sd.ID,
|
||||
RPOrigin: sd.OriginConsole,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &WebAuthN{
|
||||
web: web,
|
||||
webLogin: webLogin,
|
||||
webConsole: webConsole,
|
||||
}, err
|
||||
}
|
||||
|
||||
@ -39,7 +50,7 @@ func (u *webUser) WebAuthnID() []byte {
|
||||
}
|
||||
|
||||
func (u *webUser) WebAuthnName() string {
|
||||
return u.UserName
|
||||
return u.PreferredLoginName
|
||||
}
|
||||
|
||||
func (u *webUser) WebAuthnDisplayName() string {
|
||||
@ -54,7 +65,7 @@ func (u *webUser) WebAuthnCredentials() []webauthn.Credential {
|
||||
return u.credentials
|
||||
}
|
||||
|
||||
func (w *WebAuthN) BeginRegistration(user *usr_model.User, authType usr_model.AuthenticatorAttachment, userVerification usr_model.UserVerificationRequirement, webAuthNs ...*usr_model.WebAuthNToken) (*usr_model.WebAuthNToken, error) {
|
||||
func (w *WebAuthN) BeginRegistration(user *usr_model.User, authType usr_model.AuthenticatorAttachment, userVerification usr_model.UserVerificationRequirement, isLoginUI bool, webAuthNs ...*usr_model.WebAuthNToken) (*usr_model.WebAuthNToken, error) {
|
||||
creds := WebAuthNsToCredentials(webAuthNs)
|
||||
existing := make([]protocol.CredentialDescriptor, len(creds))
|
||||
for i, cred := range creds {
|
||||
@ -63,7 +74,7 @@ func (w *WebAuthN) BeginRegistration(user *usr_model.User, authType usr_model.Au
|
||||
CredentialID: cred.ID,
|
||||
}
|
||||
}
|
||||
credentialOptions, sessionData, err := w.web.BeginRegistration(
|
||||
credentialOptions, sessionData, err := w.web(isLoginUI).BeginRegistration(
|
||||
&webUser{
|
||||
User: user,
|
||||
credentials: creds,
|
||||
@ -90,7 +101,7 @@ func (w *WebAuthN) BeginRegistration(user *usr_model.User, authType usr_model.Au
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (w *WebAuthN) FinishRegistration(user *usr_model.User, webAuthN *usr_model.WebAuthNToken, tokenName string, credData []byte) (*usr_model.WebAuthNToken, error) {
|
||||
func (w *WebAuthN) FinishRegistration(user *usr_model.User, webAuthN *usr_model.WebAuthNToken, tokenName string, credData []byte, isLoginUI bool) (*usr_model.WebAuthNToken, error) {
|
||||
if webAuthN == nil {
|
||||
return nil, caos_errs.ThrowInternal(nil, "WEBAU-5M9so", "Errors.User.WebAuthN.NotFound")
|
||||
}
|
||||
@ -99,7 +110,7 @@ func (w *WebAuthN) FinishRegistration(user *usr_model.User, webAuthN *usr_model.
|
||||
return nil, caos_errs.ThrowInternal(err, "WEBAU-sEr8c", "Errors.User.WebAuthN.ErrorOnParseCredential")
|
||||
}
|
||||
sessionData := WebAuthNToSessionData(webAuthN)
|
||||
credential, err := w.web.CreateCredential(
|
||||
credential, err := w.web(isLoginUI).CreateCredential(
|
||||
&webUser{
|
||||
User: user,
|
||||
},
|
||||
@ -117,8 +128,8 @@ func (w *WebAuthN) FinishRegistration(user *usr_model.User, webAuthN *usr_model.
|
||||
return webAuthN, nil
|
||||
}
|
||||
|
||||
func (w *WebAuthN) BeginLogin(user *usr_model.User, userVerification usr_model.UserVerificationRequirement, webAuthNs ...*usr_model.WebAuthNToken) (*usr_model.WebAuthNLogin, error) {
|
||||
assertion, sessionData, err := w.web.BeginLogin(&webUser{
|
||||
func (w *WebAuthN) BeginLogin(user *usr_model.User, userVerification usr_model.UserVerificationRequirement, isLoginUI bool, webAuthNs ...*usr_model.WebAuthNToken) (*usr_model.WebAuthNLogin, error) {
|
||||
assertion, sessionData, err := w.web(isLoginUI).BeginLogin(&webUser{
|
||||
User: user,
|
||||
credentials: WebAuthNsToCredentials(webAuthNs),
|
||||
}, webauthn.WithUserVerification(UserVerificationFromModel(userVerification)))
|
||||
@ -137,7 +148,7 @@ func (w *WebAuthN) BeginLogin(user *usr_model.User, userVerification usr_model.U
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (w *WebAuthN) FinishLogin(user *usr_model.User, webAuthN *usr_model.WebAuthNLogin, credData []byte, webAuthNs ...*usr_model.WebAuthNToken) ([]byte, uint32, error) {
|
||||
func (w *WebAuthN) FinishLogin(user *usr_model.User, webAuthN *usr_model.WebAuthNLogin, credData []byte, isLoginUI bool, webAuthNs ...*usr_model.WebAuthNToken) ([]byte, uint32, error) {
|
||||
assertionData, err := protocol.ParseCredentialRequestResponseBody(bytes.NewReader(credData))
|
||||
if err != nil {
|
||||
return nil, 0, caos_errs.ThrowInternal(err, "WEBAU-ADgv4", "Errors.User.WebAuthN.ValidateLoginFailed")
|
||||
@ -146,7 +157,7 @@ func (w *WebAuthN) FinishLogin(user *usr_model.User, webAuthN *usr_model.WebAuth
|
||||
User: user,
|
||||
credentials: WebAuthNsToCredentials(webAuthNs),
|
||||
}
|
||||
credential, err := w.web.ValidateLogin(webUser, WebAuthNLoginToSessionData(webAuthN), assertionData)
|
||||
credential, err := w.web(isLoginUI).ValidateLogin(webUser, WebAuthNLoginToSessionData(webAuthN), assertionData)
|
||||
if err != nil {
|
||||
return nil, 0, caos_errs.ThrowInternal(err, "WEBAU-3M9si", "Errors.User.WebAuthN.ValidateLoginFailed")
|
||||
}
|
||||
@ -156,3 +167,10 @@ func (w *WebAuthN) FinishLogin(user *usr_model.User, webAuthN *usr_model.WebAuth
|
||||
}
|
||||
return credential.ID, credential.Authenticator.SignCount, nil
|
||||
}
|
||||
|
||||
func (w *WebAuthN) web(isLoginUI bool) *webauthn.WebAuthn {
|
||||
if isLoginUI {
|
||||
return w.webLogin
|
||||
}
|
||||
return w.webConsole
|
||||
}
|
||||
|
@ -656,6 +656,7 @@ message MultiFactor {
|
||||
MfaType type = 1;
|
||||
MFAState state = 2;
|
||||
string attribute = 3;
|
||||
string id = 4;
|
||||
}
|
||||
|
||||
message MfaOtpResponse {
|
||||
|
@ -2029,6 +2029,7 @@ message UserMultiFactors {
|
||||
message UserMultiFactor {
|
||||
MfaType type = 1;
|
||||
MFAState state = 2;
|
||||
string attribute = 3;
|
||||
}
|
||||
|
||||
enum MfaType {
|
||||
|
169
site/package-lock.json
generated
169
site/package-lock.json
generated
@ -25,19 +25,19 @@
|
||||
"dev": true
|
||||
},
|
||||
"@babel/core": {
|
||||
"version": "7.12.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.3.tgz",
|
||||
"integrity": "sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g==",
|
||||
"version": "7.12.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz",
|
||||
"integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.10.4",
|
||||
"@babel/generator": "^7.12.1",
|
||||
"@babel/generator": "^7.12.5",
|
||||
"@babel/helper-module-transforms": "^7.12.1",
|
||||
"@babel/helpers": "^7.12.1",
|
||||
"@babel/parser": "^7.12.3",
|
||||
"@babel/template": "^7.10.4",
|
||||
"@babel/traverse": "^7.12.1",
|
||||
"@babel/types": "^7.12.1",
|
||||
"@babel/helpers": "^7.12.5",
|
||||
"@babel/parser": "^7.12.7",
|
||||
"@babel/template": "^7.12.7",
|
||||
"@babel/traverse": "^7.12.9",
|
||||
"@babel/types": "^7.12.7",
|
||||
"convert-source-map": "^1.7.0",
|
||||
"debug": "^4.1.0",
|
||||
"gensync": "^1.0.0-beta.1",
|
||||
@ -48,10 +48,55 @@
|
||||
"source-map": "^0.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/parser": {
|
||||
"version": "7.12.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.7.tgz",
|
||||
"integrity": "sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg==",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/template": {
|
||||
"version": "7.12.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz",
|
||||
"integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.10.4",
|
||||
"@babel/parser": "^7.12.7",
|
||||
"@babel/types": "^7.12.7"
|
||||
}
|
||||
},
|
||||
"@babel/traverse": {
|
||||
"version": "7.12.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.9.tgz",
|
||||
"integrity": "sha512-iX9ajqnLdoU1s1nHt36JDI9KG4k+vmI8WgjK5d+aDTwQbL2fUnzedNedssA645Ede3PM2ma1n8Q4h2ohwXgMXw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.10.4",
|
||||
"@babel/generator": "^7.12.5",
|
||||
"@babel/helper-function-name": "^7.10.4",
|
||||
"@babel/helper-split-export-declaration": "^7.11.0",
|
||||
"@babel/parser": "^7.12.7",
|
||||
"@babel/types": "^7.12.7",
|
||||
"debug": "^4.1.0",
|
||||
"globals": "^11.1.0",
|
||||
"lodash": "^4.17.19"
|
||||
}
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.12.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz",
|
||||
"integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-validator-identifier": "^7.10.4",
|
||||
"lodash": "^4.17.19",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
|
||||
"integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
@ -1061,9 +1106,9 @@
|
||||
}
|
||||
},
|
||||
"@formatjs/ecma402-abstract": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.4.0.tgz",
|
||||
"integrity": "sha512-Mv027hcLFjE45K8UJ8PjRpdDGfR0aManEFj1KzoN8zXNveHGEygpZGfFf/FTTMl+QEVSrPAUlyxaCApvmv47AQ==",
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.5.0.tgz",
|
||||
"integrity": "sha512-wXv36yo+mfWllweN0Fq7sUs7PUiNopn7I0JpLTe3hGu6ZMR4CV7LqK1llhB18pndwpKoafQKb1et2DCJAOW20Q==",
|
||||
"requires": {
|
||||
"tslib": "^2.0.1"
|
||||
}
|
||||
@ -1079,9 +1124,9 @@
|
||||
"integrity": "sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw=="
|
||||
},
|
||||
"@rollup/plugin-babel": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.2.1.tgz",
|
||||
"integrity": "sha512-Jd7oqFR2dzZJ3NWANDyBjwTtX/lYbZpVcmkHrfQcpvawHs9E4c0nYk5U2mfZ6I/DZcIvy506KZJi54XK/jxH7A==",
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.2.2.tgz",
|
||||
"integrity": "sha512-MjmH7GvFT4TW8xFdIeFS3wqIX646y5tACdxkTO+khbHvS3ZcVJL6vkAHLw2wqPmkhwCfWHoNsp15VYNwW6JEJA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-module-imports": "^7.10.4",
|
||||
@ -1089,9 +1134,9 @@
|
||||
}
|
||||
},
|
||||
"@rollup/plugin-commonjs": {
|
||||
"version": "15.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-15.1.0.tgz",
|
||||
"integrity": "sha512-xCQqz4z/o0h2syQ7d9LskIMvBSH4PX5PjYdpSSvgS+pQik3WahkQVNWg3D8XJeYjZoVWnIUQYDghuEMRGrmQYQ==",
|
||||
"version": "17.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-17.0.0.tgz",
|
||||
"integrity": "sha512-/omBIJG1nHQc+bgkYDuLpb/V08QyutP9amOrJRUSlYJZP+b/68gM//D8sxJe3Yry2QnYIr3QjR3x4AlxJEN3GA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@rollup/pluginutils": "^3.1.0",
|
||||
@ -1101,14 +1146,6 @@
|
||||
"is-reference": "^1.2.1",
|
||||
"magic-string": "^0.25.7",
|
||||
"resolve": "^1.17.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"estree-walker": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.1.tgz",
|
||||
"integrity": "sha512-tF0hv+Yi2Ot1cwj9eYHtxC0jB9bmjacjQs6ZBTj82H8JwUywFuc+7E83NWfNMwHXZc11mjfFcVXPe9gEP4B8dg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@rollup/plugin-json": {
|
||||
@ -1145,14 +1182,14 @@
|
||||
}
|
||||
},
|
||||
"@rollup/plugin-url": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-url/-/plugin-url-5.0.1.tgz",
|
||||
"integrity": "sha512-/dO8Ic+vR9VtMkHjmFBWzISjX0iDwrB3vLg8sy4A7hxu2Uk0J09kAXbtku7gJb1fqVcJUIByFG5d/4sgNh1DvA==",
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-url/-/plugin-url-6.0.0.tgz",
|
||||
"integrity": "sha512-UHGyoo3EbLufCZtXon/baNf75PAYT+Gs/NUgFMx2ZaDQ314PKNP0pJTrpbhDqFkZADzpkqJWyQOfJ2Nd6Qk4TA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@rollup/pluginutils": "^3.0.4",
|
||||
"make-dir": "^3.0.0",
|
||||
"mime": "^2.4.4"
|
||||
"@rollup/pluginutils": "^3.1.0",
|
||||
"make-dir": "^3.1.0",
|
||||
"mime": "^2.4.6"
|
||||
}
|
||||
},
|
||||
"@rollup/pluginutils": {
|
||||
@ -1599,9 +1636,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"globalyzer": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.4.tgz",
|
||||
"integrity": "sha512-LeguVWaxgHN0MNbWC6YljNMzHkrCny9fzjmEUdnF1kQ7wATFD1RHFRqA1qxaX2tgxGENlcxjOflopBwj3YZiXA=="
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz",
|
||||
"integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q=="
|
||||
},
|
||||
"globrex": {
|
||||
"version": "0.1.2",
|
||||
@ -1647,9 +1684,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"highlight.js": {
|
||||
"version": "10.3.2",
|
||||
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.3.2.tgz",
|
||||
"integrity": "sha512-3jRT7OUYsVsKvukNKZCtnvRcFyCJqSEIuIMsEybAXRiFSwpt65qjPd/Pr+UOdYt7WJlt+lj3+ypUsHiySBp/Jw=="
|
||||
"version": "10.4.1",
|
||||
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.4.1.tgz",
|
||||
"integrity": "sha512-yR5lWvNz7c85OhVAEAeFhVCc/GV4C30Fjzc/rCP0aCWzc1UUOPUk55dK/qdwTZHBvMZo+eZ2jpk62ndX/xMFlg=="
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "2.8.8",
|
||||
@ -1703,21 +1740,21 @@
|
||||
"dev": true
|
||||
},
|
||||
"intl-messageformat": {
|
||||
"version": "9.3.18",
|
||||
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.3.18.tgz",
|
||||
"integrity": "sha512-OKrLWppdxXtRdRCPjmRZ9Ru7UZkZJDlMl+1Vpb3sCLWK0mFpr129K+gIlIb5zrWoAH3NiYDzekBXPTRWCyHSIA==",
|
||||
"version": "9.3.20",
|
||||
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.3.20.tgz",
|
||||
"integrity": "sha512-jmpjYHE076J/0CIofrPhtUC4LfmsAhuv4JMQxytl2KJd2bim+3+gQJh+Z1vyHUzcj4fIHdt388ZGchb8f0NwOA==",
|
||||
"requires": {
|
||||
"fast-memoize": "^2.5.2",
|
||||
"intl-messageformat-parser": "6.0.16",
|
||||
"intl-messageformat-parser": "6.0.18",
|
||||
"tslib": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"intl-messageformat-parser": {
|
||||
"version": "6.0.16",
|
||||
"resolved": "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-6.0.16.tgz",
|
||||
"integrity": "sha512-Qy3Zz0vF4fhMVuW4BDqUr55LsOl9enM03wuwbP4Yg7v29rYNpf7Z76Whstu6uDLDJokrjbpgDvRcjSDTAhxKJw==",
|
||||
"version": "6.0.18",
|
||||
"resolved": "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-6.0.18.tgz",
|
||||
"integrity": "sha512-vLjACEunfi5uSUCWFLOR4PXQ9DGLpED3tM7o9zsYsOvjl0VIheoxyG0WZXnsnhn+S+Zu158M6CkuHXeNZfKRRg==",
|
||||
"requires": {
|
||||
"@formatjs/ecma402-abstract": "1.4.0",
|
||||
"@formatjs/ecma402-abstract": "1.5.0",
|
||||
"tslib": "^2.0.1"
|
||||
}
|
||||
},
|
||||
@ -1904,9 +1941,9 @@
|
||||
}
|
||||
},
|
||||
"marked": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-1.2.4.tgz",
|
||||
"integrity": "sha512-6x5TFGCTKSQBLTZtOburGxCxFEBJEGYVLwCMTBCxzvyuisGcC20UNzDSJhCr/cJ/Kmh6ulfJm10g6WWEAJ3kvg=="
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-1.2.5.tgz",
|
||||
"integrity": "sha512-2AlqgYnVPOc9WDyWu7S5DJaEZsfk6dNh/neatQ3IHUW4QLutM/VPSH9lG7bif+XjFWc9K9XR3QvR+fXuECmfdA=="
|
||||
},
|
||||
"matchit": {
|
||||
"version": "1.1.0",
|
||||
@ -2247,9 +2284,9 @@
|
||||
}
|
||||
},
|
||||
"rollup": {
|
||||
"version": "2.33.2",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.33.2.tgz",
|
||||
"integrity": "sha512-QPQ6/fWCrzHtSXkI269rhKaC7qXGghYBwXU04b1JsDZ6ibZa3DJ9D1SFAYRMgx1inDg0DaTbb3N4Z1NK/r3fhw==",
|
||||
"version": "2.34.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.34.0.tgz",
|
||||
"integrity": "sha512-dW5iLvttZzdVehjEuNJ1bWvuMEJjOWGmnuFS82WeKHTGXDkRHQeq/ExdifkSyJv9dLcR86ysKRmrIDyR6O0X8g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fsevents": "~2.1.2"
|
||||
@ -2547,15 +2584,15 @@
|
||||
}
|
||||
},
|
||||
"svelte": {
|
||||
"version": "3.29.7",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.29.7.tgz",
|
||||
"integrity": "sha512-rx0g311kBODvEWUU01DFBUl3MJuJven04bvTVFUG/w0On/wuj0PajQY/QlXcJndFxG+W1s8iXKaB418tdHWc3A==",
|
||||
"version": "3.31.0",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.31.0.tgz",
|
||||
"integrity": "sha512-r+n8UJkDqoQm1b+3tA3Lh6mHXKpcfOSOuEuIo5gE2W9wQYi64RYX/qE6CZBDDsP/H4M+N426JwY7XGH4xASvGQ==",
|
||||
"dev": true
|
||||
},
|
||||
"svelte-i18n": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/svelte-i18n/-/svelte-i18n-3.2.5.tgz",
|
||||
"integrity": "sha512-EBPEPcf3Ro7av0b8g/owlfb8fQgnYFan/9gfpRtJ5EmJ7SUUnoCD8JngN9FCKY/cBu1kg2aCUCM6XyauMuAvIA==",
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/svelte-i18n/-/svelte-i18n-3.3.0.tgz",
|
||||
"integrity": "sha512-2pIfd4G8QfB87udPugt6g2Wl/qZ0kIB60+nQKHdon7d7aFzY5qsYT2NqQgK7dnVO2Gu0R8i2kSsNzsaVSk5UsA==",
|
||||
"requires": {
|
||||
"deepmerge": "^4.2.2",
|
||||
"dlv": "^1.1.3",
|
||||
@ -2591,12 +2628,12 @@
|
||||
}
|
||||
},
|
||||
"tiny-glob": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.6.tgz",
|
||||
"integrity": "sha512-A7ewMqPu1B5PWwC3m7KVgAu96Ch5LA0w4SnEN/LbDREj/gAD0nPWboRbn8YoP9ISZXqeNAlMvKSKoEuhcfK3Pw==",
|
||||
"version": "0.2.8",
|
||||
"resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.8.tgz",
|
||||
"integrity": "sha512-vkQP7qOslq63XRX9kMswlby99kyO5OvKptw7AMwBVMjXEI7Tb61eoI5DydyEMOseyGS5anDN1VPoVxEvH01q8w==",
|
||||
"requires": {
|
||||
"globalyzer": "^0.1.0",
|
||||
"globrex": "^0.1.1"
|
||||
"globalyzer": "0.1.0",
|
||||
"globrex": "^0.1.2"
|
||||
}
|
||||
},
|
||||
"to-fast-properties": {
|
||||
|
@ -29,17 +29,17 @@
|
||||
"@babel/plugin-transform-runtime": "^7.9.0",
|
||||
"@babel/preset-env": "^7.12.1",
|
||||
"@babel/runtime": "^7.12.1",
|
||||
"@rollup/plugin-commonjs": "^15.1.0",
|
||||
"@rollup/plugin-babel": "^5.0.0",
|
||||
"@rollup/plugin-commonjs": "^17.0.0",
|
||||
"@rollup/plugin-json": "^4.0.3",
|
||||
"@rollup/plugin-node-resolve": "^10.0.0",
|
||||
"@rollup/plugin-replace": "^2.2.0",
|
||||
"@rollup/plugin-url": "^6.0.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"rollup": "^2.32.1",
|
||||
"rollup-plugin-svelte": "^6.1.0",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"@rollup/plugin-babel": "^5.0.0",
|
||||
"@rollup/plugin-replace": "^2.2.0",
|
||||
"@rollup/plugin-url": "^5.0.0",
|
||||
"sapper": "^0.28.10",
|
||||
"svelte": "^3.29.4"
|
||||
"svelte": "^3.31.0"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user