text: (window.webpackJsonp=window.webpackJsonp||[]).push([[219],{1151:function(e,n,t){"use strict";t.r(n),n.default='$ curl -H "Accept: application/json" -s \\\n    \'http://127.0.0.1:4433/self-service/recovery/flows?id=199a2c74-08ca-4f22-b24c-3de3032682f8\' | \\\n      jq\n\n{\n  "id": "199a2c74-08ca-4f22-b24c-3de3032682f8",\n  "type": "browser",\n  "expires_at": "2021-04-28T13:47:17.913580042Z",\n  "issued_at": "2021-04-28T12:47:17.913580042Z",\n  "request_url": "http://127.0.0.1:4433/self-service/recovery/browser",\n  "ui": {\n    "action": "http://127.0.0.1:4433/self-service/recovery?flow=199a2c74-08ca-4f22-b24c-3de3032682f8",\n    "method": "POST",\n    "nodes": [\n      {\n        "type": "input",\n        "group": "default",\n        "attributes": {\n          "name": "csrf_token",\n          "type": "hidden",\n          "value": "VuOjAAE4olxMvyiCzB7STotMOtQEYrABc2GDo6vIF+e8trBx+zpaCkvYf7+myIDi7duYGY4vwgp8gqxmE6BecA==",\n          "required": true,\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {}\n      },\n      {\n        "type": "input",\n        "group": "link",\n        "attributes": {\n          "name": "email",\n          "type": "email",\n          "required": true,\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {}\n      },\n      {\n        "type": "input",\n        "group": "link",\n        "attributes": {\n          "name": "method",\n          "type": "submit",\n          "value": "link",\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {\n          "label": {\n            "id": 1070005,\n            "text": "Submit",\n            "type": "info"\n          }\n        }\n      }\n    ]\n  },\n  "state": "choose_method"\n}\n'},1152:function(e,n,t){"use strict";t.r(n),n.default="import { Configuration, PublicApi } from '@ory/kratos-client';\nconst kratos = new PublicApi(new Configuration({ basePath: 'http://127.0.0.1:4433/' }));\n\nconst flowId = '' // usually something like: req.query.flow\n\nkratos.getSelfServiceRecoveryFlow(flowId)\n  .then(({ data: flow }) => {\n    console.log(flow) // see the Raw HTTP tab for the payload\n  })\n"},1153:function(e,n,t){"use strict";t.r(n),n.default='package samples\n\nimport (\n  "fmt"\n\n  "github.com/ory/kratos-client-go"\n)\n\nfunc NewKratosClient(endpoint string) *kratos.APIClient {\n  conf := kratos.NewConfiguration()\n  conf.Servers = kratos.ServerConfigurations{{URL: endpoint}}\n  return kratos.NewAPIClient(conf)\n}\n\nfunc main() {\n  c := NewKratosClient("http://127.0.0.1:4433/")\n  ctx := context.Background()\n  flowID := "" // Usually something like: res.Request.URL.Query().Get("flow")\n\n  flow, _, err := c.PublicApi.GetSelfServiceRecoveryFlow().Id(flowID).Execute()\n  if err != nil {\n    // ...\n  }\n\n  fmt.Printf("%+v", rs.Payload)\n}\n'},1154:function(e,n,t){"use strict";t.r(n),n.default='curl -s -v -X GET \\\n  -H "Accept: text/html"  \\\n  http://127.0.0.1:4433/self-service/recovery/browser\n\n> GET /self-service/recovery/browser HTTP/1.1\n> Host: 127.0.0.1:4433\n> User-Agent: curl/7.64.1\n> Accept: text/html\n>\n< HTTP/1.1 302 Found\n< Cache-Control: 0\n< Content-Type: text/html; charset=utf-8\n< Location: http://127.0.0.1:4455/recovery?flow=df607aa1-d555-4b2a-b3e4-0f5a1d2fe6f3\n< Set-Cookie: csrf_token=y4Ocu6V83BapwJwbPw/pnlRHHw40DZbjq5iuDrxl0Ds=; Path=/; Domain=127.0.0.1; Max-Age=31536000; HttpOnly\n<\n<a href="http://127.0.0.1:4455/recovery?flow=df607aa1-d555-4b2a-b3e4-0f5a1d2fe6f3">Found</a>.\n'},1155:function(e,n,t){"use strict";t.r(n),n.default='<a href="http://127.0.0.1:4433/self-service/recovery/browser">Recover Account</a>\n\n\x3c!-- or --\x3e\n\n<script>\n  const initrecovery = () => {\n    window.location.href = \'http://127.0.0.1:4433/self-service/recovery/browser\'\n  }\n<\/script>\n\n<a onClick="initrecovery">Recover Account</a>\n'},1156:function(e,n,t){"use strict";t.r(n),n.default="import React from 'react'\n\nconst MyComponent = () => (\n  <a href=\"http://127.0.0.1:4433/self-service/recovery/browser\">Recover Account</a>\n)\n"},1157:function(e,n,t){"use strict";t.r(n),n.default="express.get('/recovery', function (req, res) {\n  res.redirect(302, 'http://127.0.0.1:4433/self-service/recovery/browser')\n})\n"},1158:function(e,n,t){"use strict";t.r(n),n.default='<a href="http://127.0.0.1:4433/self-service/recovery/browser">Recover Account</a>\n'},1159:function(e,n,t){"use strict";t.r(n),n.default='$ curl -s -X GET \\\n    -H "Accept: application/json" \\\n    http://127.0.0.1:4433/self-service/recovery/api | \\\n      jq\n\n{\n  "id": "c0da5b82-f22c-4609-8467-8c7e2fbc12db",\n  "type": "api",\n  "expires_at": "2021-04-28T13:22:01.115431237Z",\n  "issued_at": "2021-04-28T12:22:01.115431237Z",\n  "request_url": "http://127.0.0.1:4433/self-service/recovery/api",\n  "ui": {\n    "action": "http://127.0.0.1:4433/self-service/recovery?flow=c0da5b82-f22c-4609-8467-8c7e2fbc12db",\n    "method": "POST",\n    "nodes": [\n      {\n        "type": "input",\n        "group": "default",\n        "attributes": {\n          "name": "csrf_token",\n          "type": "hidden",\n          "value": "",\n          "required": true,\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {}\n      },\n      {\n        "type": "input",\n        "group": "link",\n        "attributes": {\n          "name": "email",\n          "type": "email",\n          "required": true,\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {}\n      },\n      {\n        "type": "input",\n        "group": "link",\n        "attributes": {\n          "name": "method",\n          "type": "submit",\n          "value": "link",\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {\n          "label": {\n            "id": 1070005,\n            "text": "Submit",\n            "type": "info"\n          }\n        }\n      }\n    ]\n  },\n  "state": "choose_method"\n}\n'},1160:function(e,n,t){"use strict";t.r(n),n.default="import { Configuration, PublicApi } from '@ory/kratos-client';\n\nconst kratos = new PublicApi(new Configuration({ basePath: 'http://127.0.0.1:4433/' }));\n\nkratos.initializeSelfServiceRecoveryViaAPIFlow()\n  .then(({ data: flow }) => {\n    console.log(flow) // see the Raw HTTP tab for the payload\n  })\n"},1161:function(e,n,t){"use strict";t.r(n),n.default='package api\n\nimport (\n  "fmt"\n\n  "github.com/ory/kratos-client-go"\n)\n\nfunc NewKratosClient(endpoint string) *kratos.APIClient {\n  conf := kratos.NewConfiguration()\n  conf.Servers = kratos.ServerConfigurations{{URL: endpoint}}\n  return kratos.NewAPIClient(conf)\n}\n\nfunc main() {\n  c := NewKratosClient("http://127.0.0.1:4433/")\n\n  flow, _, err := c.PublicApi.InitializeSelfServiceRecoveryViaAPIFlow(context.Background()).Execute()\n  if err != nil {\n    // ...\n  }\n\n  fmt.Printf("%+v", flow)\n}\n'},1162:function(e,n,t){"use strict";t.r(n),n.default=t.p+"assets/images/browser-email-missing-69ea020a0cddbff89b491f732b1d2dd1.png"},1163:function(e,n,t){"use strict";t.r(n),n.default='$ curl -H "Accept: application/json" -s \\\n    \'http://127.0.0.1:4433/self-service/recovery/flows?id=199a2c74-08ca-4f22-b24c-3de3032682f8\' | \\\n      jq -r \'.ui.nodes[] | select(.group=="link")\'\n\n{\n  "type": "input",\n  "group": "link",\n  "attributes": {\n    "name": "email",\n    "type": "email",\n    "required": true,\n    "disabled": false\n  },\n  "messages": [\n    {\n      "id": 4000002,\n      "text": "Property email is missing.",\n      "type": "error",\n      "context": {\n        "property": "email"\n      }\n    }\n  ],\n  "meta": {}\n}\n{\n  "type": "input",\n  "group": "link",\n  "attributes": {\n    "name": "method",\n    "type": "submit",\n    "value": "link",\n    "disabled": false\n  },\n  "messages": null,\n  "meta": {\n    "label": {\n      "id": 1070005,\n      "text": "Submit",\n      "type": "info"\n    }\n  }\n}\n\n'},1164:function(e,n,t){"use strict";t.r(n),n.default=t.p+"assets/images/browser-success-8e227a51ec0b57fdf6e6d165eba4f63b.png"},1165:function(e,n,t){"use strict";t.r(n),n.default='$ curl -H "Accept: application/json" -s \\\n    \'http://127.0.0.1:4433/self-service/recovery/flows?id=199a2c74-08ca-4f22-b24c-3de3032682f8\' | \\\n      jq\n\n{\n  "id": "199a2c74-08ca-4f22-b24c-3de3032682f8",\n  "type": "browser",\n  "expires_at": "2021-04-28T13:47:17.913580042Z",\n  "issued_at": "2021-04-28T12:47:17.913580042Z",\n  "request_url": "http://127.0.0.1:4433/self-service/recovery/browser",\n  "active": "link",\n  "ui": {\n    "action": "http://127.0.0.1:4433/self-service/recovery?flow=199a2c74-08ca-4f22-b24c-3de3032682f8",\n    "method": "POST",\n    "messages": [\n      {\n        "id": 1060002,\n        "text": "An email containing a recovery link has been sent to the email address you provided.",\n        "type": "info",\n        "context": {}\n      }\n    ],\n    "nodes": [\n      {\n        "type": "input",\n        "group": "default",\n        "attributes": {\n          "name": "csrf_token",\n          "type": "hidden",\n          "value": "Vax2/oPfhwTkUOHpE6UxDuM2ob+tr3RDTpKe3OHH9H6/+WWPed1/UuM3ttR5c2OihaEDcifiBkhBcbEZWa+96Q==",\n          "required": true,\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {}\n      },\n      {\n        "type": "input",\n        "group": "link",\n        "attributes": {\n          "name": "email",\n          "type": "email",\n          "value": "foo@ory.sh",\n          "required": true,\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {}\n      },\n      {\n        "type": "input",\n        "group": "link",\n        "attributes": {\n          "name": "method",\n          "type": "submit",\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {\n          "label": {\n            "id": 1070005,\n            "text": "Submit",\n            "type": "info"\n          }\n        }\n      }\n    ]\n  },\n  "state": "sent_email"\n}\n'},1166:function(e,n,t){"use strict";t.r(n),n.default=t.p+"assets/images/browser-invalid-challenge-65c38ebdbc9abc6aea81dd25f84ba3f5.png"},1167:function(e,n,t){"use strict";t.r(n),n.default='$ curl -H "Accept: application/json" -s \\\n    \'http://127.0.0.1:4433/self-service/recovery/flows?id=db163ca2-5e03-4961-8398-c537ed6c1cb9\' | \\\n      jq\n\n{\n  "id": "db163ca2-5e03-4961-8398-c537ed6c1cb9",\n  "type": "browser",\n  "expires_at": "2021-04-28T13:54:51.358334636Z",\n  "issued_at": "2021-04-28T12:54:51.358334636Z",\n  "request_url": "http://127.0.0.1:4433/self-service/recovery?flow=199a2c74-08ca-4f22-b24c-3de3032682f8&token=XSpIPzkW4DgnJVhBG5Wjw3F123Z0ORmGrrq",\n  "ui": {\n    "action": "http://127.0.0.1:4433/self-service/recovery?flow=db163ca2-5e03-4961-8398-c537ed6c1cb9",\n    "method": "POST",\n    "messages": [\n      {\n        "id": 4060004,\n        "text": "The recovery token is invalid or has already been used. Please retry the flow.",\n        "type": "error",\n        "context": {}\n      }\n    ],\n    "nodes": [\n      {\n        "type": "input",\n        "group": "default",\n        "attributes": {\n          "name": "csrf_token",\n          "type": "hidden",\n          "value": "TZ1eswBzgOQF6VC1PdPGR9vX9JfpRiwe6ZWAKpjNwgunyE3C+nF4sgKOB4hXBZTrvUBWWmMLXhXmdq/vIKWLnA==",\n          "required": true,\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {}\n      },\n      {\n        "type": "input",\n        "group": "link",\n        "attributes": {\n          "name": "email",\n          "type": "email",\n          "required": true,\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {}\n      },\n      {\n        "type": "input",\n        "group": "link",\n        "attributes": {\n          "name": "method",\n          "type": "submit",\n          "value": "link",\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {\n          "label": {\n            "id": 1070005,\n            "text": "Submit",\n            "type": "info"\n          }\n        }\n      }\n    ]\n  },\n  "state": "choose_method"\n}\n'},1168:function(e,n,t){"use strict";t.r(n),n.default=t.p+"assets/images/browser-settings-success-c322911a938d0d41e859182da98fc284.png"},1169:function(e,n,t){"use strict";t.r(n),n.default='$ curl -s -X GET \\\n    -H "Authorization: Bearer $sessionToken"  \\\n    -H "Accept: application/json"  \\\n    \'http://127.0.0.1:4433/self-service/settings/flows?id=9b527900-2199-4221-9252-7971b3362282\' | \\\n      jq\n\n{\n  "id": "9b527900-2199-4221-9252-7971b3362282",\n  "type": "browser",\n  "expires_at": "2021-04-28T13:55:36.046466067Z",\n  "issued_at": "2021-04-28T12:55:36.046466067Z",\n  "request_url": "http://127.0.0.1:4433/self-service/recovery?flow=199a2c74-08ca-4f22-b24c-3de3032682f8&token=XSpIPzkW4DgnJVhBG5Wjw3FZ0ORmGrrq",\n  "ui": {\n    "action": "http://127.0.0.1:4433/self-service/settings?flow=9b527900-2199-4221-9252-7971b3362282",\n    "method": "POST",\n    "messages": [\n      {\n        "id": 1060001,\n        "text": "You successfully recovered your account. Please change your password or set up an alternative login method (e.g. social sign in) within the next 15.00 minutes.",\n        "type": "info",\n        "context": {\n          "privilegedSessionExpiresAt": "2021-04-28T13:10:36.050848814Z"\n        }\n      }\n    ],\n    "nodes": [\n      {\n        "type": "input",\n        "group": "default",\n        "attributes": {\n          "name": "csrf_token",\n          "type": "hidden",\n          "value": "U3r/lgEfT8rA1Lg0Eeo06oGO8mX6T4TKoe/z7rbInhvYeacbRg0IW9zrqnpU1wmQJXKiekNzdLnypx5naHXoPg==",\n          "required": true,\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {}\n      },\n      {\n        "type": "input",\n        "group": "profile",\n        "attributes": {\n          "name": "traits.email",\n          "type": "email",\n          "value": "foo@ory.sh",\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {\n          "label": {\n            "id": 1070002,\n            "text": "E-Mail",\n            "type": "info"\n          }\n        }\n      },\n      {\n        "type": "input",\n        "group": "profile",\n        "attributes": {\n          "name": "traits.name.first",\n          "type": "text",\n          "value": "Foo",\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {\n          "label": {\n            "id": 1070002,\n            "text": "First Name",\n            "type": "info"\n          }\n        }\n      },\n      {\n        "type": "input",\n        "group": "profile",\n        "attributes": {\n          "name": "traits.name.last",\n          "type": "text",\n          "value": "Bar",\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {\n          "label": {\n            "id": 1070002,\n            "text": "Last Name",\n            "type": "info"\n          }\n        }\n      },\n      {\n        "type": "input",\n        "group": "profile",\n        "attributes": {\n          "name": "method",\n          "type": "submit",\n          "value": "profile",\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {\n          "label": {\n            "id": 1070003,\n            "text": "Save",\n            "type": "info"\n          }\n        }\n      },\n      {\n        "type": "input",\n        "group": "password",\n        "attributes": {\n          "name": "password",\n          "type": "password",\n          "required": true,\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {\n          "label": {\n            "id": 1070001,\n            "text": "Password",\n            "type": "info"\n          }\n        }\n      },\n      {\n        "type": "input",\n        "group": "password",\n        "attributes": {\n          "name": "method",\n          "type": "submit",\n          "value": "password",\n          "disabled": false\n        },\n        "messages": null,\n        "meta": {\n          "label": {\n            "id": 1070003,\n            "text": "Save",\n            "type": "info"\n          }\n        }\n      }\n    ]\n  },\n  "identity": {\n    "id": "b0a31645-0b5f-436a-b46d-03f15e8e89d9",\n    "schema_id": "default",\n    "schema_url": "http://127.0.0.1:4433/schemas/default",\n    "traits": {\n      "email": "foo@ory.sh",\n      "name": {\n        "first": "Foo",\n        "last": "Bar"\n      }\n    },\n    "verifiable_addresses": [\n      {\n        "id": "e3ea2845-0e07-4631-8955-9f4ecc5f73aa",\n        "value": "foo@ory.sh",\n        "verified": true,\n        "via": "email",\n        "status": "completed",\n        "verified_at": "2021-04-28T12:41:17.342366863Z"\n      }\n    ],\n    "recovery_addresses": [\n      {\n        "id": "fd66ee7e-5751-4282-bf27-414290084c19",\n        "value": "foo@ory.sh",\n        "via": "email"\n      }\n    ]\n  },\n  "state": "show_form"\n}\n'},546:function(e,n,t){"use strict";t.r(n),t.d(n,"frontMatter",(function(){return w})),t.d(n,"metadata",(function(){return j})),t.d(n,"toc",(function(){return O})),t.d(n,"default",(function(){return T}));var a=t(3),r=t(8),i=(t(0),t(553)),s=t(556),o=t(554),l=t(572),c=t(573),d=t(574),u=t(575),p={curl:{label:"Raw HTTP",language:"shell",code:t(1151).default},js:{label:"JavaScript SDK",language:"js",code:t(1152).default},go:{label:"Go SDK",language:"go",code:t(1153).default}},m={curl:{label:"Raw HTTP",language:"shell",code:t(1154).default},html:{label:"HTML",language:"html",code:t(1155).default},jsx:{label:"ReactJS",language:"js",code:t(1156).default},node:{label:"ExpressJS",language:"html",code:t(1157).default},angular:{label:"Angular",language:"js",code:t(1158).default}},b={curl:{label:"Raw HTTP",language:"shell",code:t(1159).default},js:{label:"Node",language:"js",code:t(1160).default},go:{label:"Go",language:"go",code:t(1161).default}},f={browser:{label:"Browser UI",image:t(1162).default,alt:"Account Recovery HTML Form with validation errors"},missing:{label:"Missing Email",language:"shell",code:t(1163).default}},v={browser:{label:"Browser UI",image:t(1164).default,alt:"Account Recovery HTML Form with success message"},missing:{label:"Email Sent",language:"shell",code:t(1165).default}},h={browser:{label:"Browser UI",image:t(1166).default,alt:"Account Recovery HTML Form with an invalid challenge"},missing:{label:"Invalid Challenge",language:"shell",code:t(1167).default}},g={browser:{label:"Browser UI",image:t(1168).default,alt:"Account Recovery HTML Form with an invalid challenge"},missing:{label:"Update Credentials",language:"shell",code:t(1169).default}},y=t(578),w={id:"account-recovery",title:"Account Recovery and Password Reset"},j={unversionedId:"self-service/flows/account-recovery",id:"version-v0.6/self-service/flows/account-recovery",isDocsHomePage:!1,title:"Account Recovery and Password Reset",description:"initBrowserFlow,",source:"@site/versioned_docs/version-v0.6/self-service/flows/account-recovery.mdx",sourceDirName:"self-service/flows",slug:"/self-service/flows/account-recovery",permalink:"/kratos/docs/self-service/flows/account-recovery",editUrl:"https://github.com/ory/kratos/edit/master/docs/versioned_docs/version-v0.6/self-service/flows/account-recovery.mdx",version:"v0.6",lastUpdatedBy:"aeneasr",lastUpdatedAt:1619690398,formattedLastUpdatedAt:"4/29/2021",frontMatter:{id:"account-recovery",title:"Account Recovery and Password Reset"},sidebar:"version-v0.6/docs",previous:{title:"User Settings and Profile Updates",permalink:"/kratos/docs/self-service/flows/user-settings"},next:{title:"Email and Phone Verification and Account Activation",permalink:"/kratos/docs/self-service/flows/verify-email-account-activation"}},O=[{value:"Methods",id:"methods",children:[{value:"Recovery <code>link</code> Method",id:"recovery-link-method",children:[]}]},{value:"Initialize Recovery Flow",id:"initialize-recovery-flow",children:[{value:"Recovery for Browser Clients",id:"recovery-for-browser-clients",children:[]},{value:"Recovery for API Clients",id:"recovery-for-api-clients",children:[]}]},{value:"Recovery Flow Payloads",id:"recovery-flow-payloads",children:[{value:"Send Recovery Link to Email",id:"send-recovery-link-to-email",children:[]}]},{value:"Recovery Flow Form Rendering",id:"recovery-flow-form-rendering",children:[]},{value:"Recovery Form Validation",id:"recovery-form-validation",children:[{value:"Recovery Link via Email",id:"recovery-link-via-email",children:[]}]},{value:"Unsuccessful Recovery",id:"unsuccessful-recovery",children:[]},{value:"Successful Recovery",id:"successful-recovery",children:[]}],k={toc:O};function T(e){var n=e.components,t=Object(r.a)(e,["components"]);return Object(i.b)("wrapper",Object(a.a)({},k,t,{components:n,mdxType:"MDXLayout"}),Object(i.b)("div",{className:"admonition admonition-info alert alert--info"},Object(i.b)("div",{parentName:"div",className:"admonition-heading"},Object(i.b)("h5",{parentName:"div"},Object(i.b)("span",{parentName:"h5",className:"admonition-icon"},Object(i.b)("svg",{parentName:"span",xmlns:"http://www.w3.org/2000/svg",width:"14",height:"16",viewBox:"0 0 14 16"},Object(i.b)("path",{parentName:"svg",fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"}))),"info")),Object(i.b)("div",{parentName:"div",className:"admonition-content"},Object(i.b)("p",{parentName:"div"},"Please read the ",Object(i.b)("a",{parentName:"p",href:"/kratos/docs/self-service"},"Self-Service Flows")," overview before\ncontinuing with this document."))),Object(i.b)("p",null,"Account Recovery must be performed if access to an account needs to be\nrecovered. Common use cases include:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},'"Forgot password" flows'),Object(i.b)("li",{parentName:"ul"},'"Lost MFA device" flows'),Object(i.b)("li",{parentName:"ul"},"...")),Object(i.b)("p",null,"There are two Recovery Flow types supported in Ory Kratos:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Flows where the user sits in front of the Browser (e.g. website, single page\napp, ...)"),Object(i.b)("li",{parentName:"ul"},"Flows where API interaction is required (e.g. mobile app, Smart TV, ...)")),Object(i.b)("p",null,"The Recovery Flow can be summarized as the following state machine:"),Object(i.b)(o.a,{chart:'\nstateDiagram\n  s1: Flow is initialized\n  s2: User Interface renders Recovery Flow Forms\n  s3: Update Recovery Flow with Error Context(s)\n  s4: Recovery challenge initiated (e.g. link via email)\n  s5: Recovery completed, user logged in\n  [*] --\x3e s1 : User clicks "Recover Account"\n  s1 --\x3e s2\n  s2 --\x3e s4 : User provides valid recovery data\n  s2 --\x3e s3 : User provides invalid recovery data\n  s3 --\x3e s2\n  s4 --\x3e s5 : Challenge response valid\n  s4 --\x3e s3 : Challenge response invalid\n  s5 --\x3e [*]\n',mdxType:"Mermaid"}),Object(i.b)("p",null,"To enable recovery flows, make the following adjustments to your Ory Kratos\nconfiguration:"),Object(i.b)("pre",null,Object(i.b)("code",{parentName:"pre",className:"language-yaml",metastring:'title="path/to/config/kratos.yml"',title:'"path/to/config/kratos.yml"'},"selfservice:\n  methods:\n    link:\n      enabled: true\n  flows:\n    recovery:\n      enabled: true\n")),Object(i.b)("h2",{id:"methods"},"Methods"),Object(i.b)("p",null,"Currently, one recovery method is supported:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"The ",Object(i.b)("inlineCode",{parentName:"li"},"link")," method performs account recovery (also known as password reset) by\nsending an email containing a recovery link to the user.")),Object(i.b)("h3",{id:"recovery-link-method"},"Recovery ",Object(i.b)("inlineCode",{parentName:"h3"},"link")," Method"),Object(i.b)("p",null,"The ",Object(i.b)("inlineCode",{parentName:"p"},"link")," method is dis/enabled in the Ory Kratos config:"),Object(i.b)("pre",null,Object(i.b)("code",{parentName:"pre",className:"language-yaml",metastring:'title="path/to/my/kratos/config.yml"',title:'"path/to/my/kratos/config.yml"'},"selfservice:\n  methods:\n    link:\n      enabled: true\n      # ...\n")),Object(i.b)("p",null,"There are two email types sent by this method:"),Object(i.b)("p",null,Object(i.b)("figure",null,Object(i.b)("img",{alt:"Recovery email sent to unknown address",src:Object(s.a)("img/docs/mailslurper-recovery-unknown.png")}),Object(i.b)("figcaption",null,"If the requested email address is an unknown recovery address, an account recovery attempt email is sent to that email address."))),Object(i.b)("p",null,Object(i.b)("figure",null,Object(i.b)("img",{alt:"Recovery email sent to a known recovery address",src:Object(s.a)("img/docs/mailslurper-recovery-known.png")}),Object(i.b)("figcaption",null,"If the requested email address is a known recovery address, a recovery link is sent to that email address."))),Object(i.b)("p",null,"This prevents account enumeration attacks as explained in this\n",Object(i.b)("a",{parentName:"p",href:"https://www.troyhunt.com/website-enumeration-insanity-how-our-personal-data-is-leaked/"},"brilliant blog post by Troy Hunt"),"."),Object(i.b)("p",null,"The emails are using templates that can be customised as explained in\n",Object(i.b)("a",{parentName:"p",href:"/kratos/docs/concepts/email-sms#templates"},"Customizing E-Mail Templates"),". The\ntemplate IDs are:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Unknown email address: ",Object(i.b)("inlineCode",{parentName:"li"},"recovery_invalid")),Object(i.b)("li",{parentName:"ul"},"Known email address: ",Object(i.b)("inlineCode",{parentName:"li"},"recovery_valid"))),Object(i.b)("p",null,"You should also configure how long a session is privileged. The user will only\nbe able to update his/her password (or any other credential) for the specified\namount of time after clicking on the recovery link:"),Object(i.b)("pre",null,Object(i.b)("code",{parentName:"pre",className:"language-yaml",metastring:'title="path/to/kratos/config.yml"',title:'"path/to/kratos/config.yml"'},"selfservice:\n  flows:\n    settings:\n      privileged_session_max_age: 15m\n")),Object(i.b)("p",null,"To specify that an identity's trait is a recovery email, use the following\nIdentity JSON Schema:"),Object(i.b)("pre",null,Object(i.b)("code",{parentName:"pre",className:"language-diff"},' {\n   "$id": "https://schemas.ory.sh/presets/kratos/quickstart/email-password/identity.schema.json",\n   "$schema": "http://json-schema.org/draft-07/schema#",\n   "title": "Person",\n   "type": "object",\n   "properties": {\n     "traits": {\n       "type": "object",\n       "properties": {\n         "email": {\n           "type": "string",\n           "format": "email",\n           "ory.sh/kratos": {\n             "credentials": {\n               "password": {\n                 "identifier": true\n               }\n             },\n+            "recovery": {\n+              "via": "email"\n+            }\n           }\n         }\n       }\n       "additionalProperties": false\n     }\n   }\n }\n')),Object(i.b)("h2",{id:"initialize-recovery-flow"},"Initialize Recovery Flow"),Object(i.b)("p",null,"The first step is to initialize the Recovery Flow. This sets up Anti-CSRF tokens\nand more. Each recovery flow has a ",Object(i.b)("inlineCode",{parentName:"p"},"state")," parameter which follows the state\nmachine:"),Object(i.b)(o.a,{chart:"\nstateDiagram-v2\n\t[*] --\x3e choose_method\n\tchoose_method --\x3e sent_email\n\tsent_email --\x3e sent_email\n\tnote right of sent_email\n\t    The user may fill out the email form input again as a way to re-send the email.\n\tend note\n\tsent_email --\x3e passed_challenge\n\tpassed_challenge --\x3e [*]\n",mdxType:"Mermaid"}),Object(i.b)("p",null,"where"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},Object(i.b)("inlineCode",{parentName:"li"},"choose_method")," indicates that the user has not chosen a recovery method yet.\nThis is useful when ",Object(i.b)("inlineCode",{parentName:"li"},"link")," is not the only recovery method active."),Object(i.b)("li",{parentName:"ul"},Object(i.b)("inlineCode",{parentName:"li"},"sent_email")," implies that the recovery email has been sent out."),Object(i.b)("li",{parentName:"ul"},Object(i.b)("inlineCode",{parentName:"li"},"passed_challenge")," is set when the user has clicked the recovery link and\ncompleted the account recovery.")),Object(i.b)("h3",{id:"recovery-for-browser-clients"},"Recovery for Browser Clients"),Object(i.b)("p",null,"The Recovery Flow for browser clients relies on HTTP redirects between Ory\nKratos, your Recovery UI, and the end-user's browser:"),Object(i.b)(c.a,{flows:["recovery"],success:"Set session cookie and initialize Settings Flow",interactions:['"Recover account"'],mdxType:"SelfServiceBrowserFlow"}),Object(i.b)("p",null,"To initialize the Recovery Flow, point the Browser to the initialization\nendpoint:"),Object(i.b)(u.a,{items:m,mdxType:"CodeTabs"}),Object(i.b)("p",null,"The server responds with a HTTP 302 redirect to the Recovery UI, appending the\n",Object(i.b)("inlineCode",{parentName:"p"},"?flow=<flow-id>")," query parameter (see the curl example) to the URL configured\nhere:"),Object(i.b)("pre",null,Object(i.b)("code",{parentName:"pre",className:"language-yaml",metastring:'title="path/to/config/kratos.yml"',title:'"path/to/config/kratos.yml"'},"selfservice:\n  flows:\n    recovery:\n      # becomes http://127.0.0.1:4455/recovery?flow=df607aa1-d555-4b2a-b3e4-0f5a1d2fe6f3\n      ui_url: http://127.0.0.1:4455/recovery\n")),Object(i.b)("h3",{id:"recovery-for-api-clients"},"Recovery for API Clients"),Object(i.b)(l.a,{mdxType:"ApiWarning"}),Object(i.b)("p",null,"The Recovery Flow for API clients does not use HTTP Redirects and can be\nsummarized as follows:"),Object(i.b)(d.a,{flows:["recovery"],success:"Return session token",interactions:['"Recover account"'],mdxType:"SelfServiceApiFlow"}),Object(i.b)("p",null,"To initialize the API flow, the client calls the API-flow initialization\nendpoint\n(",Object(i.b)("a",{parentName:"p",href:"/kratos/docs/reference/api#initialize-recovery-flow-for-api-clients"},"REST API Reference"),")\nwhich returns a JSON response:"),Object(i.b)(u.a,{items:b,mdxType:"CodeTabs"}),Object(i.b)("h2",{id:"recovery-flow-payloads"},"Recovery Flow Payloads"),Object(i.b)("p",null,"Fetching the Recovery Flow\n(",Object(i.b)("a",{parentName:"p",href:"/kratos/docs/reference/api#get-recovery-flow"},"REST API Reference"),") is usually\nonly required for browser clients but also works for Recovery Flows initialized\nby API clients. All you need is a valid flow ID:"),Object(i.b)(u.a,{items:p,mdxType:"CodeTabs"}),Object(i.b)("h3",{id:"send-recovery-link-to-email"},"Send Recovery Link to Email"),Object(i.b)("div",{className:"admonition admonition-note alert alert--secondary"},Object(i.b)("div",{parentName:"div",className:"admonition-heading"},Object(i.b)("h5",{parentName:"div"},Object(i.b)("span",{parentName:"h5",className:"admonition-icon"},Object(i.b)("svg",{parentName:"span",xmlns:"http://www.w3.org/2000/svg",width:"14",height:"16",viewBox:"0 0 14 16"},Object(i.b)("path",{parentName:"svg",fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"}))),"note")),Object(i.b)("div",{parentName:"div",className:"admonition-content"},Object(i.b)("p",{parentName:"div"},"The ",Object(i.b)("inlineCode",{parentName:"p"},"link")," recovery mode will always open a link in the browser, even if it was\ninitiated by an API client. This is because the user clicks the link in his/her\nemail client, which opens the browser."))),Object(i.b)("p",null,"When the ",Object(i.b)("inlineCode",{parentName:"p"},"link")," method is enabled, it will be part of the ",Object(i.b)("inlineCode",{parentName:"p"},"methods")," payload in\nthe Recovery Flow:"),Object(i.b)("pre",null,Object(i.b)("code",{parentName:"pre",className:"language-shell",metastring:"script",script:!0},'$ curl -H "Accept: application/json" -s \\\n    \'http://127.0.0.1:4434/self-service/recovery/flows?id=199a2c74-08ca-4f22-b24c-3de3032682f8\' | \\\n      jq -r \'.ui.nodes[] | select(.group=="link")\'\n\n{\n  "type": "input",\n  "group": "link",\n  "attributes": {\n    "name": "email",\n    "type": "email",\n    "required": true,\n    "disabled": false\n  },\n  "messages": null,\n  "meta": {}\n}\n{\n  "type": "input",\n  "group": "link",\n  "attributes": {\n    "name": "method",\n    "type": "submit",\n    "value": "link",\n    "disabled": false\n  },\n  "messages": null,\n  "meta": {\n    "label": {\n      "id": 1070005,\n      "text": "Submit",\n      "type": "info"\n    }\n  }\n}\n')),Object(i.b)("h2",{id:"recovery-flow-form-rendering"},"Recovery Flow Form Rendering"),Object(i.b)("p",null,"The Recovery User Interface is a route (page / site) in your application\n(server, native app, single page app) that should render a recovery form."),Object(i.b)("p",null,"In stark contrast to other Identity Systems, Ory Kratos does not render this\nHTML. Instead, you need to implement the HTML code in your application (e.g.\nNodeJS + ExpressJS, Java, PHP, ReactJS, ...), which gives you extreme\nflexibility and customizability in your user interface flows and designs."),Object(i.b)("p",null,"You will use the Recovery Flow JSON response to render the recovery form UI,\nwhich could looks as follows depending on your programming language and web\nframework:"),Object(i.b)(y.a,{flow:"recovery",mdxType:"RenderFlow"}),Object(i.b)("h2",{id:"recovery-form-validation"},"Recovery Form Validation"),Object(i.b)("p",null,"The form payloads are then submitted to Ory Kratos which follows up with:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"An HTTP 302 Found redirect pointing to the Recovery UI for Browser Clients."),Object(i.b)("li",{parentName:"ul"},"An ",Object(i.b)("inlineCode",{parentName:"li"},"application/json")," response for API Clients.")),Object(i.b)("h3",{id:"recovery-link-via-email"},"Recovery Link via Email"),Object(i.b)("p",null,"To send the recovery email, the end-user fills out the form. There might be\nvalidation errors such as a malformed email:"),Object(i.b)(u.a,{items:f,mdxType:"CodeTabs"}),Object(i.b)("p",null,"When validation errors happen, browser clients receive a HTTP 302 Found redirect\nto the Recovery Flow UI, containing the Recovery Flow ID which includes the\nerror payloads."),Object(i.b)("p",null,"For API Clients, the server typically responds with HTTP 400 Bad Request and the\nRecovery Flow in the response payload as JSON."),Object(i.b)("h4",{id:"successful-submission"},"Successful Submission"),Object(i.b)("p",null,"On successful submission, an email will be sent to the provided address:"),Object(i.b)(u.a,{items:v,mdxType:"CodeTabs"}),Object(i.b)("h2",{id:"unsuccessful-recovery"},"Unsuccessful Recovery"),Object(i.b)("p",null,"If the recovery challenge (e.g. the link in the recovery email) is invalid or\nexpired, the user will be HTTP 302 redirected to the Recovery UI."),Object(i.b)("div",{className:"admonition admonition-note alert alert--secondary"},Object(i.b)("div",{parentName:"div",className:"admonition-heading"},Object(i.b)("h5",{parentName:"div"},Object(i.b)("span",{parentName:"h5",className:"admonition-icon"},Object(i.b)("svg",{parentName:"span",xmlns:"http://www.w3.org/2000/svg",width:"14",height:"16",viewBox:"0 0 14 16"},Object(i.b)("path",{parentName:"svg",fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"}))),"note")),Object(i.b)("div",{parentName:"div",className:"admonition-content"},Object(i.b)("p",{parentName:"div"},"When an invalid or expired challenge is used, Ory Kratos initializes a new\nAccount Recovery flow automatically. This flow will always be a Browser-based\nflow because the challenge is completed by clicking a link!"))),Object(i.b)("p",null,"The new Recovery Flow includes an error message such as the following:"),Object(i.b)(u.a,{items:h,mdxType:"CodeTabs"}),Object(i.b)("p",null,"Please keep in mind that this part of the flow always involves a Browser!"),Object(i.b)("h2",{id:"successful-recovery"},"Successful Recovery"),Object(i.b)("p",null,"Completing account recovery always results in a HTTP 302 redirect with a Ory\nKratos Login Session Cookie to the Settings UI with a Settings Flow prompting\nthe user to update their password or credentials:"),Object(i.b)(u.a,{items:g,mdxType:"CodeTabs"}))}T.isMDXComponent=!0},554:function(e,n,t){"use strict";var a=t(0),r=t.n(a),i=t(576),s=t.n(i),o=t(57),l=t.n(o),c=t(570),d=t.n(c);s.a.initialize({startOnLoad:!0,logLevel:"fatal",securityLevel:"strict",arrowMarkerAbsolute:!1,theme:"neutral",flowchart:{useMaxWidth:!0,htmlLabels:!0,rankSpacing:65,nodeSpacing:30,curve:"basis"},sequence:{useMaxWidth:!0},gantt:{useMaxWidth:!0}});n.a=function(e){var n,t=e.chart,i=Object(a.useState)(!1),o=i[0],c=i[1],u=Object(a.useState)(void 0),p=u[0],m=u[1],b=Object(a.useState)("mermaid-"+Math.random().toString(36).substr(2,-1))[0],f=function(){return c(!o)};return Object(a.useEffect)((function(){s.a.render(b,t,(function(e){m(e)}))}),[]),r.a.createElement(r.a.Fragment,null,r.a.createElement("div",{onClick:f,className:d()(l.a.graph,l.a.pointer),dangerouslySetInnerHTML:{__html:p}}),r.a.createElement("div",{onClick:f,className:d()(l.a.overlay,l.a.pointer,l.a.graph,(n={},n[l.a.visible]=o,n))},r.a.createElement("div",{onClick:function(e){return e.stopPropagation()},className:d()(l.a.backdrop,l.a.graph),dangerouslySetInnerHTML:{__html:p}})))}},568:function(e,n,t){"use strict";var a=t(0),r=t.n(a),i=t(569),s=t.n(i),o=t(562),l=t(60),c=t.n(l),d=function(e,n){if(!e)return 0;var t=n.findIndex((function(n){return n.indexOf(e)>-1}));return-1===t?0:t};n.a=function(e){var n=e.src,t=e.title,i=Object(a.useState)(""),l=i[0],u=i[1];Object(a.useEffect)((function(){var t,a,r;s()(n.replace("github.com","raw.githubusercontent.com").replace("/blob/","/")).then((function(e){return e.text()})).then((t=e,a=t.startAt,r=t.endAt,function(e){var n=e.split("\n"),t=d(a,n);t>0&&(n=["// ..."].concat(n.slice(t,-1)));var i=d(r,n);return i>0&&(n=[].concat(n.slice(0,i+1),["// ..."])),n.join("\n")})).then(u).catch(console.error)}),[]);var p="language-"+function(e){var n=e.split(".").pop();switch(n){case"jsx":return"jsx";case"tsx":return"tsx";case"ts":return"typescript";case"go":return"go";case"yaml":case"yml":return"yaml";case"js":return"javascript";case"html":return"html";case"pug":return"pug";default:return n}}(n),m='title="'+(t||function(e){var n=e.match(new RegExp("https://github.com/[^/]+/[^/]+/blob/[^/]+/(.+)","i"))||[];return n.length>=2?n[1]:e}(n))+'"';return r.a.createElement("div",{className:c.a.container},r.a.createElement(o.a,{metastring:m,className:p,children:l}))}},572:function(e,n,t){"use strict";var a=t(0),r=t.n(a);n.a=function(){return r.a.createElement("div",{className:"admonition admonition-warning alert alert--danger"},r.a.createElement("div",{className:"admonition-heading"},r.a.createElement("h5",null,r.a.createElement("span",{className:"admonition-icon"},r.a.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"12",height:"16",viewBox:"0 0 12 16"},r.a.createElement("path",{"fill-rule":"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"}))),"warning")),r.a.createElement("div",{className:"admonition-content"},r.a.createElement("p",null,"Never use API flows to implement Browser applications!"),r.a.createElement("p",null,"Using API flows in Single-Page-Apps as well as server-side apps opens up several potential attack vectors, including Login and other CSRF attacks.")))}},573:function(e,n,t){"use strict";var a=t(0),r=t.n(a),i=t(554);n.a=function(e){return r.a.createElement(r.a.Fragment,null,r.a.createElement(i.a,{chart:(n=e,t=n.flows,a=void 0===t?["login","registration","settings","..."]:t,s=n.interactions,o=void 0===s?['"Log in"','"Sign Up"','"Update Email"',"..."]:s,l=n.success,c=void 0===l?"Perform flow-specific action (e.g. create user, set session cookie, ...)":l,d=a.length>1?"<"+a.join("|")+">":""+a.join("|"),"\nsequenceDiagram\n\n  participant B as Browser\n  participant K as Ory Kratos\n  participant A as Flow UI\n\n  B->>K: Follow link to /self-service/"+d+"/browser\n  K--\x3e>K: Create and store new "+a.join(", ")+" flow\n  K->>B: HTTP 302 Found <selfservice.flows."+d+".ui_url>?flow=<flow-id>\n\n  B->>A: Opens <selfservice.flows.<"+a.join("|")+">.ui_url>?flow=<flow-id>\n  A--\x3e>K: Fetches data to render forms using /selfservice/"+d+"/flows?id=<flow-id>\n  B--\x3e>A: Fills out forms, clicks e.g. "+o.join(", ")+"\n  B->>K: Submits form\n  K--\x3e>K: Validates and processes form payloads\n\n  alt Form payload is valid\n    K->>B: "+c+"\n  else Form payload invalid\n    K--\x3e>K: Update and store flow (e.g. add form validation errors)\n    K--\x3e>B: HTTP 302 Found <selfservice.flows."+d+".ui_url>?flow=<flow-id>\n    B->>A: Opens <selfservice.flows."+d+"?flow=<flow-id>\n    A--\x3e>K: Fetches data to render form fields and errors\n    B->>K: Repeat flow with input data, submit, validate, ...\n  end\n")}),r.a.createElement("p",null,"The ",r.a.createElement("em",null,"Flow UI")," (",r.a.createElement("strong",null,"your application!"),') is responsible for rendering the actual Login and Registration HTML Forms. You can of course implement one app for rendering all the Login, Registration, ... screens, and another app (think "Service Oriented Architecture", "Micro-Services" or "Service Mesh") is responsible for rendering your Dashboards, Management Screens, and so on.'));var n,t,a,s,o,l,c,d}},574:function(e,n,t){"use strict";var a=t(0),r=t.n(a),i=t(554);n.a=function(e){return r.a.createElement(i.a,{chart:(n=e,t=n.flows,a=void 0===t?["login","registration","settings","..."]:t,s=n.interactions,o=void 0===s?['"Log in"','"Sign Up"','"Update Email"',"..."]:s,l=n.success,c=void 0===l?"Perform flow-specific action (e.g. create user, set session cookie, ...)":l,d=a.length>1?"<"+a.join("|")+">":""+a.join("|"),"\nsequenceDiagram\n  participant B as API Client\n  participant K as Ory Kratos\n\n  B->>K: REST GET /self-service/"+d+"/api\n  K--\x3e>K: Create and store new "+a.join(", ")+" flow\n  K->>B: HTTP 200 OK with flow as application/json payload\n  B--\x3e>B: Render form using e.g. Native iOS UI Elements\n  B--\x3e>B: User fills out forms, clicks e.g. "+o+"\n  B->>K: REST POST to e.g. /self-service/"+d+"?flow=...>\n  K--\x3e>K: Validates and processes payload\n  alt Form payload is valid\n    K->>B: "+c+"\n  else Form payload invalid\n    K--\x3e>K: Update and store flow (e.g. add form validation errors)\n    K->>B: Respond with e.g. HTTP 400 Bad Request and updated flow as payload\n    B--\x3e>B: Render form and validation errors using e.g. Native iOS UI Elements\n    B--\x3e>K: Repeat flow with input data, submit, validate, ...\n  end\n")});var n,t,a,s,o,l,c,d}},575:function(e,n,t){"use strict";var a=t(558),r=t(559),i=t(0),s=t.n(i),o=t(562);n.a=function(e){var n=e.items;return s.a.createElement(a.a,{defaultValue:Object.keys(n)[0],values:Object.keys(n).map((function(e){return{label:n[e].label,value:e}}))},Object.keys(n).map((function(e){return s.a.createElement(r.a,{key:e,value:e},n[e].code?s.a.createElement(o.a,{className:"language-"+n[e].language,children:n[e].code}):s.a.createElement("img",{src:n[e].image,alt:n[e].alt}))})))}},577:function(e,n,t){var a={"./locale":561,"./locale.js":561};function r(e){var n=i(e);return t(n)}function i(e){if(!t.o(a,e)){var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}return a[e]}r.keys=function(){return Object.keys(a)},r.resolve=i,e.exports=r,r.id=577},578:function(e,n,t){"use strict";var a=t(558),r=t(559),i=t(0),s=t.n(i),o=t(568),l=t.p+"assets/images/browser-61597c2d37644d2e9a6cd62143a17d19.png",c=t.p+"assets/images/browser-3fffa4ddf3b8dbaa9171845af0b1ace3.png",d=t.p+"assets/images/browser-95c5fd81e495c104256cf0460ebd835a.png",u=t.p+"assets/images/browser-22673e53b8fd2d5b86732105f965b818.png";n.a=function(e){var n,t,i=e.flow;switch(i){case"registration":n=s.a.createElement("img",{src:d,alt:"User Registration HTML Form"});break;case"login":n=s.a.createElement("img",{src:l,alt:"User Login HTML Form"});break;case"settings":n=s.a.createElement("img",{src:c,alt:"Profile Settings HTML Form"});break;case"recovery":n=s.a.createElement("img",{src:u,alt:"Account Recovery HTML Form"});break;case"verification":n=s.a.createElement("img",{src:u,alt:"Email Verification HTML Form"})}return s.a.createElement(a.a,{defaultValue:"browser",values:[{label:"Browser UI",value:"browser"},{label:"ExpressJS & Handlebars",value:"express"},{label:"ReactJS",value:"react"},{label:"React Native",value:"react-native"}]},s.a.createElement(r.a,{value:"browser"},n),s.a.createElement(r.a,{value:"express"},s.a.createElement(o.a,{lang:"js",link:"https://github.com/ory/kratos-selfservice-ui-node/blob/master/src/routes/"+i+".ts",src:"https://raw.githubusercontent.com/ory/kratos-selfservice-ui-node/master/src/routes/"+i+".ts"}),"The views can be rather simple, as Ory Kratos provides you with all the information you need for rendering the forms. The following examples use Handlebars and a generic form generator to render the Flow:",s.a.createElement(a.a,{defaultValue:"view",values:[{label:(t=i,t.charAt(0).toUpperCase()+t.slice(1)+" View"),value:"view"},{label:"Generic Form View",value:"generic-form"},{label:"Example Input Form Element",value:"input-form"}]},s.a.createElement(r.a,{value:"view"},s.a.createElement(o.a,{lang:"handlebars",link:"https://github.com/ory/kratos-selfservice-ui-node/blob/master/views/"+i+".hbs",src:"https://raw.githubusercontent.com/ory/kratos-selfservice-ui-node/master/views/"+i+".hbs"})),s.a.createElement(r.a,{value:"generic-form"},s.a.createElement(o.a,{lang:"handlebars",link:"https://github.com/ory/kratos-selfservice-ui-node/blob/master/views/partials/ui.hbs",src:"https://raw.githubusercontent.com/ory/kratos-selfservice-ui-node/master/views/partials/ui.hbs"})),s.a.createElement(r.a,{value:"input-form"},s.a.createElement(o.a,{lang:"handlebars",link:"https://github.com/ory/kratos-selfservice-ui-node/blob/master/views/partials/ui_node_input_default.hbs",src:"https://raw.githubusercontent.com/ory/kratos-selfservice-ui-node/master/views/partials/ui_node_input_default.hbs"}))),"The rest of the form partials can be found"," ",s.a.createElement("a",{href:"https://github.com/ory/kratos-selfservice-ui-node/tree/master/views/partials"},"here"),"."),s.a.createElement(r.a,{value:"react"},"A React example is currently in the making."),s.a.createElement(r.a,{value:"react-native"},"A React Native example is currently in the making."))}}}]);