mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 04:57:33 +00:00
feat(api/v2): implement U2F session check (#6339)
This commit is contained in:
@@ -14,24 +14,24 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
SessionsProjectionTable = "projections.sessions3"
|
||||
SessionsProjectionTable = "projections.sessions4"
|
||||
|
||||
SessionColumnID = "id"
|
||||
SessionColumnCreationDate = "creation_date"
|
||||
SessionColumnChangeDate = "change_date"
|
||||
SessionColumnSequence = "sequence"
|
||||
SessionColumnState = "state"
|
||||
SessionColumnResourceOwner = "resource_owner"
|
||||
SessionColumnDomain = "domain"
|
||||
SessionColumnInstanceID = "instance_id"
|
||||
SessionColumnCreator = "creator"
|
||||
SessionColumnUserID = "user_id"
|
||||
SessionColumnUserCheckedAt = "user_checked_at"
|
||||
SessionColumnPasswordCheckedAt = "password_checked_at"
|
||||
SessionColumnIntentCheckedAt = "intent_checked_at"
|
||||
SessionColumnPasskeyCheckedAt = "passkey_checked_at"
|
||||
SessionColumnMetadata = "metadata"
|
||||
SessionColumnTokenID = "token_id"
|
||||
SessionColumnID = "id"
|
||||
SessionColumnCreationDate = "creation_date"
|
||||
SessionColumnChangeDate = "change_date"
|
||||
SessionColumnSequence = "sequence"
|
||||
SessionColumnState = "state"
|
||||
SessionColumnResourceOwner = "resource_owner"
|
||||
SessionColumnInstanceID = "instance_id"
|
||||
SessionColumnCreator = "creator"
|
||||
SessionColumnUserID = "user_id"
|
||||
SessionColumnUserCheckedAt = "user_checked_at"
|
||||
SessionColumnPasswordCheckedAt = "password_checked_at"
|
||||
SessionColumnIntentCheckedAt = "intent_checked_at"
|
||||
SessionColumnWebAuthNCheckedAt = "webauthn_checked_at"
|
||||
SessionColumnWebAuthNUserVerified = "webauthn_user_verified"
|
||||
SessionColumnMetadata = "metadata"
|
||||
SessionColumnTokenID = "token_id"
|
||||
)
|
||||
|
||||
type sessionProjection struct {
|
||||
@@ -50,14 +50,14 @@ func newSessionProjection(ctx context.Context, config crdb.StatementHandlerConfi
|
||||
crdb.NewColumn(SessionColumnSequence, crdb.ColumnTypeInt64),
|
||||
crdb.NewColumn(SessionColumnState, crdb.ColumnTypeEnum),
|
||||
crdb.NewColumn(SessionColumnResourceOwner, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(SessionColumnDomain, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(SessionColumnInstanceID, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(SessionColumnCreator, crdb.ColumnTypeText),
|
||||
crdb.NewColumn(SessionColumnUserID, crdb.ColumnTypeText, crdb.Nullable()),
|
||||
crdb.NewColumn(SessionColumnUserCheckedAt, crdb.ColumnTypeTimestamp, crdb.Nullable()),
|
||||
crdb.NewColumn(SessionColumnPasswordCheckedAt, crdb.ColumnTypeTimestamp, crdb.Nullable()),
|
||||
crdb.NewColumn(SessionColumnIntentCheckedAt, crdb.ColumnTypeTimestamp, crdb.Nullable()),
|
||||
crdb.NewColumn(SessionColumnPasskeyCheckedAt, crdb.ColumnTypeTimestamp, crdb.Nullable()),
|
||||
crdb.NewColumn(SessionColumnWebAuthNCheckedAt, crdb.ColumnTypeTimestamp, crdb.Nullable()),
|
||||
crdb.NewColumn(SessionColumnWebAuthNUserVerified, crdb.ColumnTypeBool, crdb.Nullable()),
|
||||
crdb.NewColumn(SessionColumnMetadata, crdb.ColumnTypeJSONB, crdb.Nullable()),
|
||||
crdb.NewColumn(SessionColumnTokenID, crdb.ColumnTypeText, crdb.Nullable()),
|
||||
},
|
||||
@@ -90,8 +90,8 @@ func (p *sessionProjection) reducers() []handler.AggregateReducer {
|
||||
Reduce: p.reduceIntentChecked,
|
||||
},
|
||||
{
|
||||
Event: session.PasskeyCheckedType,
|
||||
Reduce: p.reducePasskeyChecked,
|
||||
Event: session.WebAuthNCheckedType,
|
||||
Reduce: p.reduceWebAuthNChecked,
|
||||
},
|
||||
{
|
||||
Event: session.TokenSetType,
|
||||
@@ -142,7 +142,6 @@ func (p *sessionProjection) reduceSessionAdded(event eventstore.Event) (*handler
|
||||
handler.NewCol(SessionColumnCreationDate, e.CreationDate()),
|
||||
handler.NewCol(SessionColumnChangeDate, e.CreationDate()),
|
||||
handler.NewCol(SessionColumnResourceOwner, e.Aggregate().ResourceOwner),
|
||||
handler.NewCol(SessionColumnDomain, e.Domain),
|
||||
handler.NewCol(SessionColumnState, domain.SessionStateActive),
|
||||
handler.NewCol(SessionColumnSequence, e.Sequence()),
|
||||
handler.NewCol(SessionColumnCreator, e.User),
|
||||
@@ -210,18 +209,18 @@ func (p *sessionProjection) reduceIntentChecked(event eventstore.Event) (*handle
|
||||
), nil
|
||||
}
|
||||
|
||||
func (p *sessionProjection) reducePasskeyChecked(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*session.PasskeyCheckedEvent)
|
||||
func (p *sessionProjection) reduceWebAuthNChecked(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*session.WebAuthNCheckedEvent)
|
||||
if !ok {
|
||||
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-WieM4", "reduce.wrong.event.type %s", session.PasskeyCheckedType)
|
||||
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-WieM4", "reduce.wrong.event.type %s", session.WebAuthNCheckedType)
|
||||
}
|
||||
|
||||
return crdb.NewUpdateStatement(
|
||||
e,
|
||||
[]handler.Column{
|
||||
handler.NewCol(SessionColumnChangeDate, e.CreationDate()),
|
||||
handler.NewCol(SessionColumnSequence, e.Sequence()),
|
||||
handler.NewCol(SessionColumnPasskeyCheckedAt, e.CheckedAt),
|
||||
handler.NewCol(SessionColumnWebAuthNCheckedAt, e.CheckedAt),
|
||||
handler.NewCol(SessionColumnWebAuthNUserVerified, e.UserVerified),
|
||||
},
|
||||
[]handler.Condition{
|
||||
handler.NewCond(SessionColumnID, e.Aggregate().ID),
|
||||
|
@@ -43,14 +43,13 @@ func TestSessionProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "INSERT INTO projections.sessions3 (id, instance_id, creation_date, change_date, resource_owner, domain, state, sequence, creator) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedStmt: "INSERT INTO projections.sessions4 (id, instance_id, creation_date, change_date, resource_owner, state, sequence, creator) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
anyArg{},
|
||||
anyArg{},
|
||||
"ro-id",
|
||||
"domain",
|
||||
domain.SessionStateActive,
|
||||
uint64(15),
|
||||
"editor-user",
|
||||
@@ -80,7 +79,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.sessions3 SET (change_date, sequence, user_id, user_checked_at) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
|
||||
expectedStmt: "UPDATE projections.sessions4 SET (change_date, sequence, user_id, user_checked_at) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
anyArg{},
|
||||
@@ -113,7 +112,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.sessions3 SET (change_date, sequence, password_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedStmt: "UPDATE projections.sessions4 SET (change_date, sequence, password_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
anyArg{},
|
||||
@@ -126,6 +125,40 @@ func TestSessionProjection_reduces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "instance reduceWebAuthNChecked",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
session.WebAuthNCheckedType,
|
||||
session.AggregateType,
|
||||
[]byte(`{
|
||||
"checkedAt": "2023-05-04T00:00:00Z",
|
||||
"userVerified": true
|
||||
}`),
|
||||
), eventstore.GenericEventMapper[session.WebAuthNCheckedEvent]),
|
||||
},
|
||||
reduce: (&sessionProjection{}).reduceWebAuthNChecked,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("session"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.sessions4 SET (change_date, sequence, webauthn_checked_at, webauthn_user_verified) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
anyArg{},
|
||||
time.Date(2023, time.May, 4, 0, 0, 0, 0, time.UTC),
|
||||
true,
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "instance reduceIntentChecked",
|
||||
args: args{
|
||||
@@ -145,7 +178,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.sessions3 SET (change_date, sequence, intent_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedStmt: "UPDATE projections.sessions4 SET (change_date, sequence, intent_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
anyArg{},
|
||||
@@ -177,7 +210,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.sessions3 SET (change_date, sequence, token_id) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedStmt: "UPDATE projections.sessions4 SET (change_date, sequence, token_id) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
anyArg{},
|
||||
@@ -211,7 +244,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.sessions3 SET (change_date, sequence, metadata) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedStmt: "UPDATE projections.sessions4 SET (change_date, sequence, metadata) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
anyArg{},
|
||||
@@ -243,7 +276,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "DELETE FROM projections.sessions3 WHERE (id = $1) AND (instance_id = $2)",
|
||||
expectedStmt: "DELETE FROM projections.sessions4 WHERE (id = $1) AND (instance_id = $2)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
"instance-id",
|
||||
@@ -270,7 +303,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "DELETE FROM projections.sessions3 WHERE (instance_id = $1)",
|
||||
expectedStmt: "DELETE FROM projections.sessions4 WHERE (instance_id = $1)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
},
|
||||
@@ -301,7 +334,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE projections.sessions3 SET password_checked_at = $1 WHERE (user_id = $2) AND (password_checked_at < $3)",
|
||||
expectedStmt: "UPDATE projections.sessions4 SET password_checked_at = $1 WHERE (user_id = $2) AND (password_checked_at < $3)",
|
||||
expectedArgs: []interface{}{
|
||||
nil,
|
||||
"agg-id",
|
||||
|
@@ -29,12 +29,11 @@ type Session struct {
|
||||
Sequence uint64
|
||||
State domain.SessionState
|
||||
ResourceOwner string
|
||||
Domain string
|
||||
Creator string
|
||||
UserFactor SessionUserFactor
|
||||
PasswordFactor SessionPasswordFactor
|
||||
IntentFactor SessionIntentFactor
|
||||
PasskeyFactor SessionPasskeyFactor
|
||||
WebAuthNFactor SessionWebAuthNFactor
|
||||
Metadata map[string][]byte
|
||||
}
|
||||
|
||||
@@ -54,8 +53,9 @@ type SessionIntentFactor struct {
|
||||
IntentCheckedAt time.Time
|
||||
}
|
||||
|
||||
type SessionPasskeyFactor struct {
|
||||
PasskeyCheckedAt time.Time
|
||||
type SessionWebAuthNFactor struct {
|
||||
WebAuthNCheckedAt time.Time
|
||||
UserVerified bool
|
||||
}
|
||||
|
||||
type SessionsSearchQueries struct {
|
||||
@@ -100,10 +100,6 @@ var (
|
||||
name: projection.SessionColumnResourceOwner,
|
||||
table: sessionsTable,
|
||||
}
|
||||
SessionColumnDomain = Column{
|
||||
name: projection.SessionColumnDomain,
|
||||
table: sessionsTable,
|
||||
}
|
||||
SessionColumnInstanceID = Column{
|
||||
name: projection.SessionColumnInstanceID,
|
||||
table: sessionsTable,
|
||||
@@ -128,8 +124,12 @@ var (
|
||||
name: projection.SessionColumnIntentCheckedAt,
|
||||
table: sessionsTable,
|
||||
}
|
||||
SessionColumnPasskeyCheckedAt = Column{
|
||||
name: projection.SessionColumnPasskeyCheckedAt,
|
||||
SessionColumnWebAuthNCheckedAt = Column{
|
||||
name: projection.SessionColumnWebAuthNCheckedAt,
|
||||
table: sessionsTable,
|
||||
}
|
||||
SessionColumnWebAuthNUserVerified = Column{
|
||||
name: projection.SessionColumnWebAuthNUserVerified,
|
||||
table: sessionsTable,
|
||||
}
|
||||
SessionColumnMetadata = Column{
|
||||
@@ -221,7 +221,6 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil
|
||||
SessionColumnState.identifier(),
|
||||
SessionColumnResourceOwner.identifier(),
|
||||
SessionColumnCreator.identifier(),
|
||||
SessionColumnDomain.identifier(),
|
||||
SessionColumnUserID.identifier(),
|
||||
SessionColumnUserCheckedAt.identifier(),
|
||||
LoginNameNameCol.identifier(),
|
||||
@@ -229,7 +228,8 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil
|
||||
UserResourceOwnerCol.identifier(),
|
||||
SessionColumnPasswordCheckedAt.identifier(),
|
||||
SessionColumnIntentCheckedAt.identifier(),
|
||||
SessionColumnPasskeyCheckedAt.identifier(),
|
||||
SessionColumnWebAuthNCheckedAt.identifier(),
|
||||
SessionColumnWebAuthNUserVerified.identifier(),
|
||||
SessionColumnMetadata.identifier(),
|
||||
SessionColumnToken.identifier(),
|
||||
).From(sessionsTable.identifier()).
|
||||
@@ -240,17 +240,17 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil
|
||||
session := new(Session)
|
||||
|
||||
var (
|
||||
userID sql.NullString
|
||||
userCheckedAt sql.NullTime
|
||||
loginName sql.NullString
|
||||
displayName sql.NullString
|
||||
userResourceOwner sql.NullString
|
||||
passwordCheckedAt sql.NullTime
|
||||
intentCheckedAt sql.NullTime
|
||||
passkeyCheckedAt sql.NullTime
|
||||
metadata database.Map[[]byte]
|
||||
token sql.NullString
|
||||
sessionDomain sql.NullString
|
||||
userID sql.NullString
|
||||
userCheckedAt sql.NullTime
|
||||
loginName sql.NullString
|
||||
displayName sql.NullString
|
||||
userResourceOwner sql.NullString
|
||||
passwordCheckedAt sql.NullTime
|
||||
intentCheckedAt sql.NullTime
|
||||
webAuthNCheckedAt sql.NullTime
|
||||
webAuthNUserPresent sql.NullBool
|
||||
metadata database.Map[[]byte]
|
||||
token sql.NullString
|
||||
)
|
||||
|
||||
err := row.Scan(
|
||||
@@ -261,7 +261,6 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil
|
||||
&session.State,
|
||||
&session.ResourceOwner,
|
||||
&session.Creator,
|
||||
&sessionDomain,
|
||||
&userID,
|
||||
&userCheckedAt,
|
||||
&loginName,
|
||||
@@ -269,7 +268,8 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil
|
||||
&userResourceOwner,
|
||||
&passwordCheckedAt,
|
||||
&intentCheckedAt,
|
||||
&passkeyCheckedAt,
|
||||
&webAuthNCheckedAt,
|
||||
&webAuthNUserPresent,
|
||||
&metadata,
|
||||
&token,
|
||||
)
|
||||
@@ -281,7 +281,6 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil
|
||||
return nil, "", errors.ThrowInternal(err, "QUERY-SAder", "Errors.Internal")
|
||||
}
|
||||
|
||||
session.Domain = sessionDomain.String
|
||||
session.UserFactor.UserID = userID.String
|
||||
session.UserFactor.UserCheckedAt = userCheckedAt.Time
|
||||
session.UserFactor.LoginName = loginName.String
|
||||
@@ -289,7 +288,8 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil
|
||||
session.UserFactor.ResourceOwner = userResourceOwner.String
|
||||
session.PasswordFactor.PasswordCheckedAt = passwordCheckedAt.Time
|
||||
session.IntentFactor.IntentCheckedAt = intentCheckedAt.Time
|
||||
session.PasskeyFactor.PasskeyCheckedAt = passkeyCheckedAt.Time
|
||||
session.WebAuthNFactor.WebAuthNCheckedAt = webAuthNCheckedAt.Time
|
||||
session.WebAuthNFactor.UserVerified = webAuthNUserPresent.Bool
|
||||
session.Metadata = metadata
|
||||
|
||||
return session, token.String, nil
|
||||
@@ -305,7 +305,6 @@ func prepareSessionsQuery(ctx context.Context, db prepareDatabase) (sq.SelectBui
|
||||
SessionColumnState.identifier(),
|
||||
SessionColumnResourceOwner.identifier(),
|
||||
SessionColumnCreator.identifier(),
|
||||
SessionColumnDomain.identifier(),
|
||||
SessionColumnUserID.identifier(),
|
||||
SessionColumnUserCheckedAt.identifier(),
|
||||
LoginNameNameCol.identifier(),
|
||||
@@ -313,7 +312,8 @@ func prepareSessionsQuery(ctx context.Context, db prepareDatabase) (sq.SelectBui
|
||||
UserResourceOwnerCol.identifier(),
|
||||
SessionColumnPasswordCheckedAt.identifier(),
|
||||
SessionColumnIntentCheckedAt.identifier(),
|
||||
SessionColumnPasskeyCheckedAt.identifier(),
|
||||
SessionColumnWebAuthNCheckedAt.identifier(),
|
||||
SessionColumnWebAuthNUserVerified.identifier(),
|
||||
SessionColumnMetadata.identifier(),
|
||||
countColumn.identifier(),
|
||||
).From(sessionsTable.identifier()).
|
||||
@@ -327,16 +327,16 @@ func prepareSessionsQuery(ctx context.Context, db prepareDatabase) (sq.SelectBui
|
||||
session := new(Session)
|
||||
|
||||
var (
|
||||
userID sql.NullString
|
||||
userCheckedAt sql.NullTime
|
||||
loginName sql.NullString
|
||||
displayName sql.NullString
|
||||
userResourceOwner sql.NullString
|
||||
passwordCheckedAt sql.NullTime
|
||||
intentCheckedAt sql.NullTime
|
||||
passkeyCheckedAt sql.NullTime
|
||||
metadata database.Map[[]byte]
|
||||
sessionDomain sql.NullString
|
||||
userID sql.NullString
|
||||
userCheckedAt sql.NullTime
|
||||
loginName sql.NullString
|
||||
displayName sql.NullString
|
||||
userResourceOwner sql.NullString
|
||||
passwordCheckedAt sql.NullTime
|
||||
intentCheckedAt sql.NullTime
|
||||
webAuthNCheckedAt sql.NullTime
|
||||
webAuthNUserPresent sql.NullBool
|
||||
metadata database.Map[[]byte]
|
||||
)
|
||||
|
||||
err := rows.Scan(
|
||||
@@ -347,7 +347,6 @@ func prepareSessionsQuery(ctx context.Context, db prepareDatabase) (sq.SelectBui
|
||||
&session.State,
|
||||
&session.ResourceOwner,
|
||||
&session.Creator,
|
||||
&sessionDomain,
|
||||
&userID,
|
||||
&userCheckedAt,
|
||||
&loginName,
|
||||
@@ -355,7 +354,8 @@ func prepareSessionsQuery(ctx context.Context, db prepareDatabase) (sq.SelectBui
|
||||
&userResourceOwner,
|
||||
&passwordCheckedAt,
|
||||
&intentCheckedAt,
|
||||
&passkeyCheckedAt,
|
||||
&webAuthNCheckedAt,
|
||||
&webAuthNUserPresent,
|
||||
&metadata,
|
||||
&sessions.Count,
|
||||
)
|
||||
@@ -363,7 +363,6 @@ func prepareSessionsQuery(ctx context.Context, db prepareDatabase) (sq.SelectBui
|
||||
if err != nil {
|
||||
return nil, errors.ThrowInternal(err, "QUERY-SAfeg", "Errors.Internal")
|
||||
}
|
||||
session.Domain = sessionDomain.String
|
||||
session.UserFactor.UserID = userID.String
|
||||
session.UserFactor.UserCheckedAt = userCheckedAt.Time
|
||||
session.UserFactor.LoginName = loginName.String
|
||||
@@ -371,7 +370,8 @@ func prepareSessionsQuery(ctx context.Context, db prepareDatabase) (sq.SelectBui
|
||||
session.UserFactor.ResourceOwner = userResourceOwner.String
|
||||
session.PasswordFactor.PasswordCheckedAt = passwordCheckedAt.Time
|
||||
session.IntentFactor.IntentCheckedAt = intentCheckedAt.Time
|
||||
session.PasskeyFactor.PasskeyCheckedAt = passkeyCheckedAt.Time
|
||||
session.WebAuthNFactor.WebAuthNCheckedAt = webAuthNCheckedAt.Time
|
||||
session.WebAuthNFactor.UserVerified = webAuthNUserPresent.Bool
|
||||
session.Metadata = metadata
|
||||
|
||||
sessions.Sessions = append(sessions.Sessions, session)
|
||||
|
@@ -17,51 +17,51 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
expectedSessionQuery = regexp.QuoteMeta(`SELECT projections.sessions3.id,` +
|
||||
` projections.sessions3.creation_date,` +
|
||||
` projections.sessions3.change_date,` +
|
||||
` projections.sessions3.sequence,` +
|
||||
` projections.sessions3.state,` +
|
||||
` projections.sessions3.resource_owner,` +
|
||||
` projections.sessions3.creator,` +
|
||||
` projections.sessions3.domain,` +
|
||||
` projections.sessions3.user_id,` +
|
||||
` projections.sessions3.user_checked_at,` +
|
||||
expectedSessionQuery = regexp.QuoteMeta(`SELECT projections.sessions4.id,` +
|
||||
` projections.sessions4.creation_date,` +
|
||||
` projections.sessions4.change_date,` +
|
||||
` projections.sessions4.sequence,` +
|
||||
` projections.sessions4.state,` +
|
||||
` projections.sessions4.resource_owner,` +
|
||||
` projections.sessions4.creator,` +
|
||||
` projections.sessions4.user_id,` +
|
||||
` projections.sessions4.user_checked_at,` +
|
||||
` projections.login_names2.login_name,` +
|
||||
` projections.users8_humans.display_name,` +
|
||||
` projections.users8.resource_owner,` +
|
||||
` projections.sessions3.password_checked_at,` +
|
||||
` projections.sessions3.intent_checked_at,` +
|
||||
` projections.sessions3.passkey_checked_at,` +
|
||||
` projections.sessions3.metadata,` +
|
||||
` projections.sessions3.token_id` +
|
||||
` FROM projections.sessions3` +
|
||||
` LEFT JOIN projections.login_names2 ON projections.sessions3.user_id = projections.login_names2.user_id AND projections.sessions3.instance_id = projections.login_names2.instance_id` +
|
||||
` LEFT JOIN projections.users8_humans ON projections.sessions3.user_id = projections.users8_humans.user_id AND projections.sessions3.instance_id = projections.users8_humans.instance_id` +
|
||||
` LEFT JOIN projections.users8 ON projections.sessions3.user_id = projections.users8.id AND projections.sessions3.instance_id = projections.users8.instance_id` +
|
||||
` projections.sessions4.password_checked_at,` +
|
||||
` projections.sessions4.intent_checked_at,` +
|
||||
` projections.sessions4.webauthn_checked_at,` +
|
||||
` projections.sessions4.webauthn_user_verified,` +
|
||||
` projections.sessions4.metadata,` +
|
||||
` projections.sessions4.token_id` +
|
||||
` FROM projections.sessions4` +
|
||||
` LEFT JOIN projections.login_names2 ON projections.sessions4.user_id = projections.login_names2.user_id AND projections.sessions4.instance_id = projections.login_names2.instance_id` +
|
||||
` LEFT JOIN projections.users8_humans ON projections.sessions4.user_id = projections.users8_humans.user_id AND projections.sessions4.instance_id = projections.users8_humans.instance_id` +
|
||||
` LEFT JOIN projections.users8 ON projections.sessions4.user_id = projections.users8.id AND projections.sessions4.instance_id = projections.users8.instance_id` +
|
||||
` AS OF SYSTEM TIME '-1 ms'`)
|
||||
expectedSessionsQuery = regexp.QuoteMeta(`SELECT projections.sessions3.id,` +
|
||||
` projections.sessions3.creation_date,` +
|
||||
` projections.sessions3.change_date,` +
|
||||
` projections.sessions3.sequence,` +
|
||||
` projections.sessions3.state,` +
|
||||
` projections.sessions3.resource_owner,` +
|
||||
` projections.sessions3.creator,` +
|
||||
` projections.sessions3.domain,` +
|
||||
` projections.sessions3.user_id,` +
|
||||
` projections.sessions3.user_checked_at,` +
|
||||
expectedSessionsQuery = regexp.QuoteMeta(`SELECT projections.sessions4.id,` +
|
||||
` projections.sessions4.creation_date,` +
|
||||
` projections.sessions4.change_date,` +
|
||||
` projections.sessions4.sequence,` +
|
||||
` projections.sessions4.state,` +
|
||||
` projections.sessions4.resource_owner,` +
|
||||
` projections.sessions4.creator,` +
|
||||
` projections.sessions4.user_id,` +
|
||||
` projections.sessions4.user_checked_at,` +
|
||||
` projections.login_names2.login_name,` +
|
||||
` projections.users8_humans.display_name,` +
|
||||
` projections.users8.resource_owner,` +
|
||||
` projections.sessions3.password_checked_at,` +
|
||||
` projections.sessions3.intent_checked_at,` +
|
||||
` projections.sessions3.passkey_checked_at,` +
|
||||
` projections.sessions3.metadata,` +
|
||||
` projections.sessions4.password_checked_at,` +
|
||||
` projections.sessions4.intent_checked_at,` +
|
||||
` projections.sessions4.webauthn_checked_at,` +
|
||||
` projections.sessions4.webauthn_user_verified,` +
|
||||
` projections.sessions4.metadata,` +
|
||||
` COUNT(*) OVER ()` +
|
||||
` FROM projections.sessions3` +
|
||||
` LEFT JOIN projections.login_names2 ON projections.sessions3.user_id = projections.login_names2.user_id AND projections.sessions3.instance_id = projections.login_names2.instance_id` +
|
||||
` LEFT JOIN projections.users8_humans ON projections.sessions3.user_id = projections.users8_humans.user_id AND projections.sessions3.instance_id = projections.users8_humans.instance_id` +
|
||||
` LEFT JOIN projections.users8 ON projections.sessions3.user_id = projections.users8.id AND projections.sessions3.instance_id = projections.users8.instance_id` +
|
||||
` FROM projections.sessions4` +
|
||||
` LEFT JOIN projections.login_names2 ON projections.sessions4.user_id = projections.login_names2.user_id AND projections.sessions4.instance_id = projections.login_names2.instance_id` +
|
||||
` LEFT JOIN projections.users8_humans ON projections.sessions4.user_id = projections.users8_humans.user_id AND projections.sessions4.instance_id = projections.users8_humans.instance_id` +
|
||||
` LEFT JOIN projections.users8 ON projections.sessions4.user_id = projections.users8.id AND projections.sessions4.instance_id = projections.users8.instance_id` +
|
||||
` AS OF SYSTEM TIME '-1 ms'`)
|
||||
|
||||
sessionCols = []string{
|
||||
@@ -72,7 +72,6 @@ var (
|
||||
"state",
|
||||
"resource_owner",
|
||||
"creator",
|
||||
"domain",
|
||||
"user_id",
|
||||
"user_checked_at",
|
||||
"login_name",
|
||||
@@ -80,7 +79,8 @@ var (
|
||||
"user_resource_owner",
|
||||
"password_checked_at",
|
||||
"intent_checked_at",
|
||||
"passkey_checked_at",
|
||||
"webauthn_checked_at",
|
||||
"webauthn_user_verified",
|
||||
"metadata",
|
||||
"token",
|
||||
}
|
||||
@@ -93,7 +93,6 @@ var (
|
||||
"state",
|
||||
"resource_owner",
|
||||
"creator",
|
||||
"domain",
|
||||
"user_id",
|
||||
"user_checked_at",
|
||||
"login_name",
|
||||
@@ -101,7 +100,8 @@ var (
|
||||
"user_resource_owner",
|
||||
"password_checked_at",
|
||||
"intent_checked_at",
|
||||
"passkey_checked_at",
|
||||
"webauthn_checked_at",
|
||||
"webauthn_user_verified",
|
||||
"metadata",
|
||||
"count",
|
||||
}
|
||||
@@ -146,7 +146,6 @@ func Test_SessionsPrepare(t *testing.T) {
|
||||
domain.SessionStateActive,
|
||||
"ro",
|
||||
"creator",
|
||||
"domain",
|
||||
"user-id",
|
||||
testNow,
|
||||
"login-name",
|
||||
@@ -155,6 +154,7 @@ func Test_SessionsPrepare(t *testing.T) {
|
||||
testNow,
|
||||
testNow,
|
||||
testNow,
|
||||
true,
|
||||
[]byte(`{"key": "dmFsdWU="}`),
|
||||
},
|
||||
},
|
||||
@@ -173,7 +173,6 @@ func Test_SessionsPrepare(t *testing.T) {
|
||||
State: domain.SessionStateActive,
|
||||
ResourceOwner: "ro",
|
||||
Creator: "creator",
|
||||
Domain: "domain",
|
||||
UserFactor: SessionUserFactor{
|
||||
UserID: "user-id",
|
||||
UserCheckedAt: testNow,
|
||||
@@ -187,8 +186,9 @@ func Test_SessionsPrepare(t *testing.T) {
|
||||
IntentFactor: SessionIntentFactor{
|
||||
IntentCheckedAt: testNow,
|
||||
},
|
||||
PasskeyFactor: SessionPasskeyFactor{
|
||||
PasskeyCheckedAt: testNow,
|
||||
WebAuthNFactor: SessionWebAuthNFactor{
|
||||
WebAuthNCheckedAt: testNow,
|
||||
UserVerified: true,
|
||||
},
|
||||
Metadata: map[string][]byte{
|
||||
"key": []byte("value"),
|
||||
@@ -213,7 +213,6 @@ func Test_SessionsPrepare(t *testing.T) {
|
||||
domain.SessionStateActive,
|
||||
"ro",
|
||||
"creator",
|
||||
"domain",
|
||||
"user-id",
|
||||
testNow,
|
||||
"login-name",
|
||||
@@ -222,6 +221,7 @@ func Test_SessionsPrepare(t *testing.T) {
|
||||
testNow,
|
||||
testNow,
|
||||
testNow,
|
||||
true,
|
||||
[]byte(`{"key": "dmFsdWU="}`),
|
||||
},
|
||||
{
|
||||
@@ -232,7 +232,6 @@ func Test_SessionsPrepare(t *testing.T) {
|
||||
domain.SessionStateActive,
|
||||
"ro",
|
||||
"creator2",
|
||||
"domain",
|
||||
"user-id2",
|
||||
testNow,
|
||||
"login-name2",
|
||||
@@ -241,6 +240,7 @@ func Test_SessionsPrepare(t *testing.T) {
|
||||
testNow,
|
||||
testNow,
|
||||
testNow,
|
||||
false,
|
||||
[]byte(`{"key": "dmFsdWU="}`),
|
||||
},
|
||||
},
|
||||
@@ -259,7 +259,6 @@ func Test_SessionsPrepare(t *testing.T) {
|
||||
State: domain.SessionStateActive,
|
||||
ResourceOwner: "ro",
|
||||
Creator: "creator",
|
||||
Domain: "domain",
|
||||
UserFactor: SessionUserFactor{
|
||||
UserID: "user-id",
|
||||
UserCheckedAt: testNow,
|
||||
@@ -273,8 +272,9 @@ func Test_SessionsPrepare(t *testing.T) {
|
||||
IntentFactor: SessionIntentFactor{
|
||||
IntentCheckedAt: testNow,
|
||||
},
|
||||
PasskeyFactor: SessionPasskeyFactor{
|
||||
PasskeyCheckedAt: testNow,
|
||||
WebAuthNFactor: SessionWebAuthNFactor{
|
||||
WebAuthNCheckedAt: testNow,
|
||||
UserVerified: true,
|
||||
},
|
||||
Metadata: map[string][]byte{
|
||||
"key": []byte("value"),
|
||||
@@ -288,7 +288,6 @@ func Test_SessionsPrepare(t *testing.T) {
|
||||
State: domain.SessionStateActive,
|
||||
ResourceOwner: "ro",
|
||||
Creator: "creator2",
|
||||
Domain: "domain",
|
||||
UserFactor: SessionUserFactor{
|
||||
UserID: "user-id2",
|
||||
UserCheckedAt: testNow,
|
||||
@@ -302,8 +301,9 @@ func Test_SessionsPrepare(t *testing.T) {
|
||||
IntentFactor: SessionIntentFactor{
|
||||
IntentCheckedAt: testNow,
|
||||
},
|
||||
PasskeyFactor: SessionPasskeyFactor{
|
||||
PasskeyCheckedAt: testNow,
|
||||
WebAuthNFactor: SessionWebAuthNFactor{
|
||||
WebAuthNCheckedAt: testNow,
|
||||
UserVerified: false,
|
||||
},
|
||||
Metadata: map[string][]byte{
|
||||
"key": []byte("value"),
|
||||
@@ -381,7 +381,6 @@ func Test_SessionPrepare(t *testing.T) {
|
||||
domain.SessionStateActive,
|
||||
"ro",
|
||||
"creator",
|
||||
"domain",
|
||||
"user-id",
|
||||
testNow,
|
||||
"login-name",
|
||||
@@ -390,6 +389,7 @@ func Test_SessionPrepare(t *testing.T) {
|
||||
testNow,
|
||||
testNow,
|
||||
testNow,
|
||||
true,
|
||||
[]byte(`{"key": "dmFsdWU="}`),
|
||||
"tokenID",
|
||||
},
|
||||
@@ -403,7 +403,6 @@ func Test_SessionPrepare(t *testing.T) {
|
||||
State: domain.SessionStateActive,
|
||||
ResourceOwner: "ro",
|
||||
Creator: "creator",
|
||||
Domain: "domain",
|
||||
UserFactor: SessionUserFactor{
|
||||
UserID: "user-id",
|
||||
UserCheckedAt: testNow,
|
||||
@@ -417,8 +416,9 @@ func Test_SessionPrepare(t *testing.T) {
|
||||
IntentFactor: SessionIntentFactor{
|
||||
IntentCheckedAt: testNow,
|
||||
},
|
||||
PasskeyFactor: SessionPasskeyFactor{
|
||||
PasskeyCheckedAt: testNow,
|
||||
WebAuthNFactor: SessionWebAuthNFactor{
|
||||
WebAuthNCheckedAt: testNow,
|
||||
UserVerified: true,
|
||||
},
|
||||
Metadata: map[string][]byte{
|
||||
"key": []byte("value"),
|
||||
|
Reference in New Issue
Block a user