snapshot of https://github.com/ory/kratos.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
This commit is contained in:
148
identity/credentials_migrate.go
Normal file
148
identity/credentials_migrate.go
Normal file
@@ -0,0 +1,148 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package identity
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
"github.com/tidwall/sjson"
|
||||
|
||||
"github.com/ory/kratos/x"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func UpgradeWebAuthnCredentials(i *Identity, c *Credentials) (err error) {
|
||||
if c.Type != CredentialsTypeWebAuthn {
|
||||
return nil
|
||||
}
|
||||
|
||||
version := c.Version
|
||||
if version == 0 {
|
||||
if gjson.GetBytes(c.Config, "user_handle").String() == "" {
|
||||
id, err := json.Marshal(i.ID[:])
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
c.Config, err = sjson.SetRawBytes(c.Config, "user_handle", id)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
index := -1
|
||||
var err error
|
||||
gjson.GetBytes(c.Config, "credentials").ForEach(func(_, value gjson.Result) bool {
|
||||
index++
|
||||
|
||||
if value.Get("is_passwordless").Exists() {
|
||||
return true
|
||||
}
|
||||
|
||||
c.Config, err = sjson.SetBytes(c.Config, fmt.Sprintf("credentials.%d.is_passwordless", index), false)
|
||||
return err == nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
c.Version = 1
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpgradeCredentials migrates a set of older WebAuthn, Code, and
|
||||
// Password credentials to newer ones.
|
||||
func UpgradeCredentials(i *Identity) error {
|
||||
for k := range i.Credentials {
|
||||
c := i.Credentials[k]
|
||||
if err := UpgradeWebAuthnCredentials(i, &c); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if err := UpgradeCodeCredentials(&c); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if err := UpgradePasswordCredentials(&c); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
i.Credentials[k] = c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func UpgradeCodeCredentials(c *Credentials) (err error) {
|
||||
if c.Type != CredentialsTypeCodeAuth {
|
||||
return nil
|
||||
}
|
||||
|
||||
version := c.Version
|
||||
if version == 0 {
|
||||
addressType := strings.ToLower(strings.TrimSpace(gjson.GetBytes(c.Config, "address_type").String()))
|
||||
|
||||
channel, err := NewCodeChannel(addressType)
|
||||
if err != nil {
|
||||
// We know that in some cases the address type can be empty. In this case, we default to email
|
||||
// as sms is a new addition to the address_type introduced in this PR.
|
||||
channel = CodeChannelEmail
|
||||
}
|
||||
|
||||
c.Config, err = sjson.DeleteBytes(c.Config, "used_at")
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
c.Config, err = sjson.DeleteBytes(c.Config, "address_type")
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
for _, id := range c.Identifiers {
|
||||
if id == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
c.Config, err = sjson.SetBytes(c.Config, "addresses.-1", &CredentialsCodeAddress{
|
||||
Address: id,
|
||||
Channel: channel,
|
||||
})
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
// This is needed because sjson adds spaces which can trip string comparisons.
|
||||
c.Config, err = json.Marshal(json.RawMessage(c.Config))
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
c.Version = 1
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpgradePasswordCredentials will make a graceful attempt to normalize
|
||||
// the format of a credential's identifier. Version is always bumped to v1.
|
||||
func UpgradePasswordCredentials(c *Credentials) (err error) {
|
||||
if c.Type != CredentialsTypePassword {
|
||||
return nil
|
||||
}
|
||||
|
||||
if c.Version == 0 {
|
||||
// iterate over identifier values
|
||||
// and normalize format
|
||||
for i := range c.Identifiers {
|
||||
c.Identifiers[i] = x.GracefulNormalization(c.Identifiers[i])
|
||||
}
|
||||
slices.Sort(c.Identifiers)
|
||||
c.Identifiers = slices.Compact(c.Identifiers)
|
||||
c.Version = 1
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user