mirror of https://github.com/ory/kratos
520 lines
12 KiB
Go
520 lines
12 KiB
Go
// Copyright © 2023 Ory Corp
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package node
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/ory/kratos/text"
|
|
"github.com/ory/kratos/x/webauthnx/js"
|
|
)
|
|
|
|
const (
|
|
InputAttributeTypeText UiNodeInputAttributeType = "text"
|
|
InputAttributeTypePassword UiNodeInputAttributeType = "password"
|
|
InputAttributeTypeNumber UiNodeInputAttributeType = "number"
|
|
InputAttributeTypeCheckbox UiNodeInputAttributeType = "checkbox"
|
|
InputAttributeTypeHidden UiNodeInputAttributeType = "hidden"
|
|
InputAttributeTypeEmail UiNodeInputAttributeType = "email"
|
|
InputAttributeTypeTel UiNodeInputAttributeType = "tel"
|
|
InputAttributeTypeSubmit UiNodeInputAttributeType = "submit"
|
|
InputAttributeTypeButton UiNodeInputAttributeType = "button"
|
|
InputAttributeTypeDateTimeLocal UiNodeInputAttributeType = "datetime-local"
|
|
InputAttributeTypeDate UiNodeInputAttributeType = "date"
|
|
InputAttributeTypeURI UiNodeInputAttributeType = "url"
|
|
)
|
|
|
|
const (
|
|
InputAttributeAutocompleteEmail UiNodeInputAttributeAutocomplete = "email"
|
|
InputAttributeAutocompleteTel UiNodeInputAttributeAutocomplete = "tel"
|
|
InputAttributeAutocompleteUrl UiNodeInputAttributeAutocomplete = "url"
|
|
InputAttributeAutocompleteCurrentPassword UiNodeInputAttributeAutocomplete = "current-password"
|
|
InputAttributeAutocompleteNewPassword UiNodeInputAttributeAutocomplete = "new-password"
|
|
InputAttributeAutocompleteOneTimeCode UiNodeInputAttributeAutocomplete = "one-time-code"
|
|
InputAttributeAutocompleteUsernameWebauthn UiNodeInputAttributeAutocomplete = "username webauthn"
|
|
)
|
|
|
|
// swagger:enum UiNodeInputAttributeType
|
|
type UiNodeInputAttributeType string
|
|
|
|
// swagger:enum UiNodeInputAttributeAutocomplete
|
|
type UiNodeInputAttributeAutocomplete string
|
|
|
|
// Attributes represents a list of attributes (e.g. `href="foo"` for links).
|
|
//
|
|
// swagger:model uiNodeAttributes
|
|
type Attributes interface {
|
|
// swagger:ignore
|
|
ID() string
|
|
|
|
// swagger:ignore
|
|
Reset()
|
|
|
|
// swagger:ignore
|
|
SetValue(value interface{})
|
|
|
|
// swagger:ignore
|
|
GetValue() interface{}
|
|
|
|
// swagger:ignore
|
|
GetNodeType() UiNodeType
|
|
|
|
// swagger:ignore
|
|
Matches(other Attributes) bool
|
|
}
|
|
|
|
// InputAttributes represents the attributes of an input node
|
|
//
|
|
// swagger:model uiNodeInputAttributes
|
|
type InputAttributes struct {
|
|
// The input's element name.
|
|
//
|
|
// required: true
|
|
Name string `json:"name"`
|
|
|
|
// The input's element type.
|
|
//
|
|
// required: true
|
|
Type UiNodeInputAttributeType `json:"type" faker:"-"`
|
|
|
|
// The input's value.
|
|
FieldValue interface{} `json:"value,omitempty" faker:"string"`
|
|
|
|
// Mark this input field as required.
|
|
Required bool `json:"required,omitempty"`
|
|
|
|
// The autocomplete attribute for the input.
|
|
Autocomplete UiNodeInputAttributeAutocomplete `json:"autocomplete,omitempty"`
|
|
|
|
// The input's label text.
|
|
Label *text.Message `json:"label,omitempty"`
|
|
|
|
// The input's pattern.
|
|
Pattern string `json:"pattern,omitempty"`
|
|
|
|
// Sets the input's disabled field to true or false.
|
|
//
|
|
// required: true
|
|
Disabled bool `json:"disabled"`
|
|
|
|
// OnClick may contain javascript which should be executed on click. This is primarily
|
|
// used for WebAuthn.
|
|
//
|
|
// Deprecated: Using OnClick requires the use of eval() which is a security risk. Use OnClickTrigger instead.
|
|
OnClick string `json:"onclick,omitempty"`
|
|
|
|
// OnClickTrigger may contain a WebAuthn trigger which should be executed on click.
|
|
//
|
|
// The trigger maps to a JavaScript function provided by Ory, which triggers actions such as PassKey registration or login.
|
|
OnClickTrigger js.WebAuthnTriggers `json:"onclickTrigger,omitempty"`
|
|
|
|
// OnLoad may contain javascript which should be executed on load. This is primarily
|
|
// used for WebAuthn.
|
|
//
|
|
// Deprecated: Using OnLoad requires the use of eval() which is a security risk. Use OnLoadTrigger instead.
|
|
OnLoad string `json:"onload,omitempty"`
|
|
|
|
// OnLoadTrigger may contain a WebAuthn trigger which should be executed on load.
|
|
//
|
|
// The trigger maps to a JavaScript function provided by Ory, which triggers actions such as PassKey registration or login.
|
|
OnLoadTrigger js.WebAuthnTriggers `json:"onloadTrigger,omitempty"`
|
|
|
|
// MaxLength may contain the input's maximum length.
|
|
MaxLength int `json:"maxlength,omitempty"`
|
|
|
|
// NodeType represents this node's types. It is a mirror of `node.type` and
|
|
// is primarily used to allow compatibility with OpenAPI 3.0. In this struct it technically always is "input".
|
|
//
|
|
// required: true
|
|
NodeType UiNodeType `json:"node_type"`
|
|
}
|
|
|
|
// ImageAttributes represents the attributes of an image node.
|
|
//
|
|
// swagger:model uiNodeImageAttributes
|
|
type ImageAttributes struct {
|
|
// The image's source URL.
|
|
//
|
|
// format: uri
|
|
// required: true
|
|
Source string `json:"src"`
|
|
|
|
// A unique identifier
|
|
//
|
|
// required: true
|
|
Identifier string `json:"id"`
|
|
|
|
// Width of the image
|
|
//
|
|
// required: true
|
|
Width int `json:"width"`
|
|
|
|
// Height of the image
|
|
//
|
|
// required: true
|
|
Height int `json:"height"`
|
|
|
|
// NodeType represents this node's types. It is a mirror of `node.type` and
|
|
// is primarily used to allow compatibility with OpenAPI 3.0. In this struct it technically always is "img".
|
|
//
|
|
// required: true
|
|
NodeType UiNodeType `json:"node_type"`
|
|
}
|
|
|
|
// AnchorAttributes represents the attributes of an anchor node.
|
|
//
|
|
// swagger:model uiNodeAnchorAttributes
|
|
type AnchorAttributes struct {
|
|
// The link's href (destination) URL.
|
|
//
|
|
// format: uri
|
|
// required: true
|
|
HREF string `json:"href"`
|
|
|
|
// The link's title.
|
|
//
|
|
// required: true
|
|
Title *text.Message `json:"title"`
|
|
|
|
// A unique identifier
|
|
//
|
|
// required: true
|
|
Identifier string `json:"id"`
|
|
|
|
// NodeType represents this node's types. It is a mirror of `node.type` and
|
|
// is primarily used to allow compatibility with OpenAPI 3.0. In this struct it technically always is "a".
|
|
//
|
|
// required: true
|
|
NodeType UiNodeType `json:"node_type"`
|
|
}
|
|
|
|
// TextAttributes represents the attributes of a text node.
|
|
//
|
|
// swagger:model uiNodeTextAttributes
|
|
type TextAttributes struct {
|
|
// The text of the text node.
|
|
//
|
|
// required: true
|
|
Text *text.Message `json:"text"`
|
|
|
|
// A unique identifier
|
|
//
|
|
// required: true
|
|
Identifier string `json:"id"`
|
|
|
|
// NodeType represents this node's types. It is a mirror of `node.type` and
|
|
// is primarily used to allow compatibility with OpenAPI 3.0. In this struct it technically always is "text".
|
|
//
|
|
// required: true
|
|
NodeType UiNodeType `json:"node_type"`
|
|
}
|
|
|
|
// ScriptAttributes represent script nodes which load javascript.
|
|
//
|
|
// swagger:model uiNodeScriptAttributes
|
|
type ScriptAttributes struct {
|
|
// The script source
|
|
//
|
|
// required: true
|
|
Source string `json:"src"`
|
|
|
|
// The script async type
|
|
//
|
|
// required: true
|
|
Async bool `json:"async"`
|
|
|
|
// The script referrer policy
|
|
//
|
|
// required: true
|
|
ReferrerPolicy string `json:"referrerpolicy"`
|
|
|
|
// The script cross origin policy
|
|
//
|
|
// required: true
|
|
CrossOrigin string `json:"crossorigin"`
|
|
|
|
// The script's integrity hash
|
|
//
|
|
// required: true
|
|
Integrity string `json:"integrity"`
|
|
|
|
// The script MIME type
|
|
//
|
|
// required: true
|
|
Type string `json:"type"`
|
|
|
|
// A unique identifier
|
|
//
|
|
// required: true
|
|
Identifier string `json:"id"`
|
|
|
|
// Nonce for CSP
|
|
//
|
|
// A nonce you may want to use to improve your Content Security Policy.
|
|
// You do not have to use this value but if you want to improve your CSP
|
|
// policies you may use it. You can also choose to use your own nonce value!
|
|
//
|
|
// required: true
|
|
Nonce string `json:"nonce"`
|
|
|
|
// NodeType represents this node's types. It is a mirror of `node.type` and
|
|
// is primarily used to allow compatibility with OpenAPI 3.0. In this struct it technically always is "script".
|
|
//
|
|
// required: true
|
|
NodeType UiNodeType `json:"node_type"`
|
|
}
|
|
|
|
// DivisionAttributes represent a division section.
|
|
//
|
|
// Division sections are used for interactive widgets that require a hook in the DOM / view.
|
|
//
|
|
// swagger:model uiNodeDivisionAttributes
|
|
type DivisionAttributes struct {
|
|
// A classname that should be rendered into the DOM.
|
|
Classname string `json:"class,omitzero"`
|
|
|
|
// A unique identifier
|
|
//
|
|
// required: true
|
|
Identifier string `json:"id"`
|
|
|
|
// Data is a map of key-value pairs that are passed to the division.
|
|
//
|
|
// They may be used for `data-...` attributes.
|
|
Data map[string]string `json:"data,omitzero"`
|
|
|
|
// NodeType represents this node's type. It is a mirror of `node.type` and
|
|
// is primarily used to allow compatibility with OpenAPI 3.0. In this struct it technically always is "script".
|
|
//
|
|
// required: true
|
|
NodeType UiNodeType `json:"node_type"`
|
|
}
|
|
|
|
func (d DivisionAttributes) ID() string {
|
|
return d.Identifier
|
|
}
|
|
|
|
func (d DivisionAttributes) Reset() {}
|
|
|
|
func (d DivisionAttributes) SetValue(_ interface{}) {}
|
|
|
|
func (d DivisionAttributes) GetValue() interface{} {
|
|
return nil
|
|
}
|
|
|
|
func (d DivisionAttributes) GetNodeType() UiNodeType {
|
|
return d.NodeType
|
|
}
|
|
|
|
func (d DivisionAttributes) Matches(other Attributes) bool {
|
|
ot, ok := other.(*DivisionAttributes)
|
|
if !ok {
|
|
return false
|
|
}
|
|
|
|
if len(ot.ID()) > 0 && d.ID() != ot.ID() {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
var (
|
|
_ Attributes = new(InputAttributes)
|
|
_ Attributes = new(ImageAttributes)
|
|
_ Attributes = new(AnchorAttributes)
|
|
_ Attributes = new(TextAttributes)
|
|
_ Attributes = new(ScriptAttributes)
|
|
_ Attributes = new(DivisionAttributes)
|
|
)
|
|
|
|
func (a *InputAttributes) ID() string {
|
|
return a.Name
|
|
}
|
|
|
|
func (a *ImageAttributes) ID() string {
|
|
return a.Identifier
|
|
}
|
|
|
|
func (a *AnchorAttributes) ID() string {
|
|
return a.Identifier
|
|
}
|
|
|
|
func (a *TextAttributes) ID() string {
|
|
return a.Identifier
|
|
}
|
|
|
|
func (a *ScriptAttributes) ID() string {
|
|
return a.Identifier
|
|
}
|
|
|
|
func (a *InputAttributes) Matches(other Attributes) bool {
|
|
ot, ok := other.(*InputAttributes)
|
|
if !ok {
|
|
return false
|
|
}
|
|
|
|
if len(ot.ID()) > 0 && a.ID() != ot.ID() {
|
|
return false
|
|
}
|
|
|
|
if len(ot.Type) > 0 && a.Type != ot.Type {
|
|
return false
|
|
}
|
|
|
|
if ot.FieldValue != nil && fmt.Sprintf("%v", a.FieldValue) != fmt.Sprintf("%v", ot.FieldValue) {
|
|
return false
|
|
}
|
|
|
|
if len(ot.Name) > 0 && a.Name != ot.Name {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (a *ImageAttributes) Matches(other Attributes) bool {
|
|
ot, ok := other.(*ImageAttributes)
|
|
if !ok {
|
|
return false
|
|
}
|
|
|
|
if len(ot.ID()) > 0 && a.ID() != ot.ID() {
|
|
return false
|
|
}
|
|
|
|
if len(ot.Source) > 0 && a.Source != ot.Source {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (a *AnchorAttributes) Matches(other Attributes) bool {
|
|
ot, ok := other.(*AnchorAttributes)
|
|
if !ok {
|
|
return false
|
|
}
|
|
|
|
if len(ot.ID()) > 0 && a.ID() != ot.ID() {
|
|
return false
|
|
}
|
|
|
|
if len(ot.HREF) > 0 && a.HREF != ot.HREF {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (a *TextAttributes) Matches(other Attributes) bool {
|
|
ot, ok := other.(*TextAttributes)
|
|
if !ok {
|
|
return false
|
|
}
|
|
|
|
if len(ot.ID()) > 0 && a.ID() != ot.ID() {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (a *ScriptAttributes) Matches(other Attributes) bool {
|
|
ot, ok := other.(*ScriptAttributes)
|
|
if !ok {
|
|
return false
|
|
}
|
|
|
|
if len(ot.ID()) > 0 && a.ID() != ot.ID() {
|
|
return false
|
|
}
|
|
|
|
if ot.Type != "" && a.Type != ot.Type {
|
|
return false
|
|
}
|
|
|
|
if ot.Source != "" && a.Source != ot.Source {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (a *InputAttributes) SetValue(value interface{}) {
|
|
a.FieldValue = value
|
|
}
|
|
|
|
func (a *ImageAttributes) SetValue(value interface{}) {
|
|
a.Source, _ = value.(string)
|
|
}
|
|
|
|
func (a *AnchorAttributes) SetValue(value interface{}) {
|
|
a.HREF, _ = value.(string)
|
|
}
|
|
|
|
func (a *TextAttributes) SetValue(value interface{}) {
|
|
a.Text, _ = value.(*text.Message)
|
|
}
|
|
|
|
func (a *ScriptAttributes) SetValue(value interface{}) {
|
|
a.Source, _ = value.(string)
|
|
}
|
|
|
|
func (a *InputAttributes) GetValue() interface{} {
|
|
return a.FieldValue
|
|
}
|
|
|
|
func (a *ImageAttributes) GetValue() interface{} {
|
|
return a.Source
|
|
}
|
|
|
|
func (a *AnchorAttributes) GetValue() interface{} {
|
|
return a.HREF
|
|
}
|
|
|
|
func (a *TextAttributes) GetValue() interface{} {
|
|
return a.Text
|
|
}
|
|
|
|
func (a *ScriptAttributes) GetValue() interface{} {
|
|
return a.Source
|
|
}
|
|
|
|
func (a *InputAttributes) Reset() {
|
|
a.FieldValue = nil
|
|
}
|
|
|
|
func (a *ImageAttributes) Reset() {
|
|
}
|
|
|
|
func (a *AnchorAttributes) Reset() {
|
|
}
|
|
|
|
func (a *TextAttributes) Reset() {
|
|
}
|
|
|
|
func (a *ScriptAttributes) Reset() {
|
|
}
|
|
|
|
func (a *InputAttributes) GetNodeType() UiNodeType {
|
|
return UiNodeType(a.NodeType)
|
|
}
|
|
|
|
func (a *ImageAttributes) GetNodeType() UiNodeType {
|
|
return UiNodeType(a.NodeType)
|
|
}
|
|
|
|
func (a *AnchorAttributes) GetNodeType() UiNodeType {
|
|
return UiNodeType(a.NodeType)
|
|
}
|
|
|
|
func (a *TextAttributes) GetNodeType() UiNodeType {
|
|
return UiNodeType(a.NodeType)
|
|
}
|
|
|
|
func (a *ScriptAttributes) GetNodeType() UiNodeType {
|
|
return UiNodeType(a.NodeType)
|
|
}
|