swagger:route POST /self-service/verification frontend updateVerificationFlow # Complete Verification Flow Use this endpoint to complete a verification flow. This endpoint behaves differently for API and browser flows and has several states: - `choose_method` expects `flow` (in the URL query) and
(w http.ResponseWriter, r *http.Request)
| 416 | // Extensions: |
| 417 | // x-ory-ratelimit-bucket: kratos-public-high |
| 418 | func (h *Handler) updateVerificationFlow(w http.ResponseWriter, r *http.Request) { |
| 419 | rid, err := flow.GetFlowID(r) |
| 420 | if err != nil { |
| 421 | h.d.VerificationFlowErrorHandler().WriteFlowError(w, r, nil, node.DefaultGroup, err) |
| 422 | return |
| 423 | } |
| 424 | |
| 425 | ctx := r.Context() |
| 426 | f, err := h.d.VerificationFlowPersister().GetVerificationFlow(ctx, rid) |
| 427 | if errors.Is(err, sqlcon.ErrNoRows) { |
| 428 | h.d.VerificationFlowErrorHandler().WriteFlowError(w, r, nil, node.DefaultGroup, errors.WithStack(herodot.ErrNotFound.WithReasonf("The verification request could not be found. Please restart the flow."))) |
| 429 | return |
| 430 | } else if err != nil { |
| 431 | h.d.VerificationFlowErrorHandler().WriteFlowError(w, r, nil, node.DefaultGroup, err) |
| 432 | return |
| 433 | } |
| 434 | |
| 435 | if err := f.Valid(); err != nil { |
| 436 | h.d.VerificationFlowErrorHandler().WriteFlowError(w, r, f, node.DefaultGroup, err) |
| 437 | return |
| 438 | } |
| 439 | |
| 440 | var g node.UiNodeGroup |
| 441 | var found bool |
| 442 | for _, ss := range h.d.AllVerificationStrategies() { |
| 443 | // If a primary strategy is set, but it does not match the current strategy, that strategy is not responsible anyways. |
| 444 | if ps, isPrimary := ss.(PrimaryStrategy); isPrimary && f.Active.String() != "" && f.Active.String() != ps.VerificationStrategyID() { |
| 445 | continue |
| 446 | } |
| 447 | |
| 448 | err := ss.Verify(w, r, f) |
| 449 | if errors.Is(err, flow.ErrStrategyNotResponsible) { |
| 450 | continue |
| 451 | } else if errors.Is(err, flow.ErrCompletedByStrategy) { |
| 452 | return |
| 453 | } else if err != nil { |
| 454 | h.d.VerificationFlowErrorHandler().WriteFlowError(w, r, f, ss.NodeGroup(), err) |
| 455 | return |
| 456 | } |
| 457 | |
| 458 | found = true |
| 459 | g = ss.NodeGroup() |
| 460 | break |
| 461 | } |
| 462 | |
| 463 | if !found { |
| 464 | h.d.VerificationFlowErrorHandler().WriteFlowError(w, r, f, node.DefaultGroup, errors.WithStack(schema.NewNoVerificationStrategyResponsible())) |
| 465 | return |
| 466 | } |
| 467 | |
| 468 | // API flows can receive requests from the browser, if the link strategy is used. |
| 469 | // However, x.IsBrowserRequest only checks for form submissions, not JSON requests made from a browser context |
| 470 | if x.IsBrowserRequest(r) || (f.Type == flow.TypeBrowser && x.IsJSONRequest(r)) { |
| 471 | // Special case: If we ended up here through a OAuth2 login challenge, we need to accept the login request |
| 472 | // and redirect back to the OAuth2 provider. |
| 473 | if flow.HasReachedState(flow.StatePassedChallenge, f.State) && f.OAuth2LoginChallenge.String() != "" { |
| 474 | if !f.IdentityID.Valid || !f.SessionID.Valid { |
| 475 | h.d.VerificationFlowErrorHandler().WriteFlowError(w, r, f, node.DefaultGroup, |
nothing calls this directly
no test coverage detected