|
5 | 5 | "fmt"
|
6 | 6 | auditlog "github.com/teamhanko/hanko/backend/audit_log"
|
7 | 7 | "github.com/teamhanko/hanko/backend/flow_api/flow/shared"
|
| 8 | + "github.com/teamhanko/hanko/backend/flow_api/services" |
8 | 9 | "github.com/teamhanko/hanko/backend/flowpilot"
|
9 | 10 | "github.com/teamhanko/hanko/backend/persistence/models"
|
10 | 11 | "regexp"
|
@@ -197,13 +198,48 @@ func (a ContinueWithLoginIdentifier) Execute(c flowpilot.ExecutionContext) error
|
197 | 198 | }
|
198 | 199 |
|
199 | 200 | if deps.Cfg.Privacy.OnlyShowActualLoginMethods {
|
| 201 | + emailAvailable := deps.Cfg.Email.UseForAuthentication && userModel != nil && userModel.Emails.GetPrimary() != nil |
| 202 | + passwordAvailable := deps.Cfg.Password.Enabled && userModel != nil && userModel.PasswordCredential != nil |
| 203 | + passkeysAvailable := deps.Cfg.Passkey.Enabled && userModel != nil && len(userModel.GetPasskeys()) > 0 |
| 204 | + availableMethods := 0 |
| 205 | + if emailAvailable { |
| 206 | + availableMethods += 1 |
| 207 | + } |
| 208 | + if passwordAvailable { |
| 209 | + availableMethods += 1 |
| 210 | + } |
| 211 | + if passkeysAvailable { |
| 212 | + availableMethods += 1 |
| 213 | + } |
| 214 | + |
200 | 215 | switch {
|
201 |
| - case deps.Cfg.Email.UseForAuthentication && userModel != nil && userModel.Emails.GetPrimary() != nil && deps.Cfg.Password.Enabled && userModel.PasswordCredential != nil: |
| 216 | + case availableMethods > 1: |
202 | 217 | return c.Continue(shared.StateLoginMethodChooser)
|
203 |
| - case deps.Cfg.Email.UseForAuthentication && userModel != nil && userModel.Emails.GetPrimary() != nil: |
| 218 | + case emailAvailable: |
204 | 219 | return a.continueToPasscodeConfirmation(c)
|
205 |
| - case deps.Cfg.Password.Enabled && userModel != nil && userModel.PasswordCredential != nil: |
| 220 | + case passwordAvailable: |
206 | 221 | return c.Continue(shared.StateLoginPassword)
|
| 222 | + case passkeysAvailable: |
| 223 | + //goland:noinspection GoDfaNilDereference |
| 224 | + userModel.WebauthnCredentials = userModel.GetPasskeys() |
| 225 | + params := services.GenerateRequestOptionsPasskeyParams{Tx: deps.Tx, User: userModel} |
| 226 | + |
| 227 | + sessionDataModel, requestOptions, err := deps.WebauthnService.GenerateRequestOptionsPasskey(params) |
| 228 | + if err != nil { |
| 229 | + return fmt.Errorf("failed to generate webauthn request options: %w", err) |
| 230 | + } |
| 231 | + |
| 232 | + err = c.Stash().Set(shared.StashPathWebauthnSessionDataID, sessionDataModel.ID.String()) |
| 233 | + if err != nil { |
| 234 | + return fmt.Errorf("failed to stash webauthn_session_data_id: %w", err) |
| 235 | + } |
| 236 | + |
| 237 | + err = c.Payload().Set("request_options", requestOptions) |
| 238 | + if err != nil { |
| 239 | + return fmt.Errorf("failed to set request_options payload: %w", err) |
| 240 | + } |
| 241 | + |
| 242 | + return c.Continue(shared.StateLoginPasskey) |
207 | 243 | }
|
208 | 244 | } else {
|
209 | 245 | if deps.Cfg.Email.UseForAuthentication && deps.Cfg.Password.Enabled {
|
|
0 commit comments