1"use strict";(globalThis.webpackChunkwebsite=globalThis.webpackChunkwebsite||[]).push([[8526],{8544(e,s,n){n.r(s),n.d(s,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"dashboard/setup","title":"Setup","description":"The Setup screen appears the first time you open the Routerly dashboard at http3000/dashboard. It guides you through creating the first admin account.","source":"@site/versioned_docs/version-0.2.0/dashboard/setup.md","sourceDirName":"dashboard","slug":"/dashboard/setup","permalink":"/dashboard/setup","draft":false,"unlisted":false,"editUrl":"https://github.com/Inebrio/Routerly/edit/main/versioned_docs/version-0.2.0/dashboard/setup.md","tags":[],"version":"0.2.0","sidebarPosition":1,"frontMatter":{"title":"Setup","sidebar_position":1},"sidebar":"docsSidebar","previous":{"title":"Provider Adapters","permalink":"/service/providers"},"next":{"title":"Overview","permalink":"/dashboard/overview"}}');var r=n(4848),i=n(8453);const a={title:"Setup",sidebar_position:1},o="Setup",d={},c=[{value:"First-Time Setup",id:"first-time-setup",level:2},{value:"Setup API",id:"setup-api",level:2},{value:"Subsequent Admin Accounts",id:"subsequent-admin-accounts",level:2},{value:"Resetting the Admin Password",id:"resetting-the-admin-password",level:2}];function l(e){const s={admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"setup",children:"Setup"})}),"\n",(0,r.jsxs)(s.p,{children:["The Setup screen appears the first time you open the Routerly dashboard at ",(0,r.jsx)(s.code,{children:"http://localhost:3000/dashboard"}),". It guides you through creating the first admin account."]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"first-time-setup",children:"First-Time Setup"}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["Open ",(0,r.jsx)(s.code,{children:"http://localhost:3000/dashboard"})," in your browser."]}),"\n",(0,r.jsxs)(s.li,{children:["You will be redirected to the ",(0,r.jsx)(s.strong,{children:"Setup"})," page automatically if no admin account exists yet."]}),"\n",(0,r.jsxs)(s.li,{children:["Enter an ",(0,r.jsx)(s.strong,{children:"email address"})," and a ",(0,r.jsx)(s.strong,{children:"password"})," for the admin account."]}),"\n",(0,r.jsxs)(s.li,{children:["Click ",(0,r.jsx)(s.strong,{children:"Create Account"}),"."]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"After account creation you are redirected to the login page. Log in with the credentials you just created."}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"setup-api",children:"Setup API"}),"\n",(0,r.jsx)(s.p,{children:"The setup state can be checked programmatically:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"# Check whether setup has been completed\nGET /api/setup/status\n"})}),"\n",(0,r.jsx)(s.p,{children:"Response when setup is not yet done:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-json",children:'{ "configured": false }\n'})}),"\n",(0,r.jsx)(s.p,{children:"Response after setup:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-json",children:'{ "configured": true }\n'})}),"\n",(0,r.jsxs)(s.p,{children:["The first-admin endpoint is only available when ",(0,r.jsx)(s.code,{children:"configured: false"}),":"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:'POST /api/setup/first-admin\nContent-Type: application/json\n\n{\n "email": "[email protected]",\n "password": "your-secure-password"\n}\n'})}),"\n",(0,r.jsxs)(s.p,{children:["Once an admin account exists, this endpoint returns ",(0,r.jsx)(s.code,{children:"403 Forbidden"}),"."]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"subsequent-admin-accounts",children:"Subsequent Admin Accounts"}),"\n",(0,r.jsxs)(s.p,{children:["After setup is complete, additional admin users can be created from ",(0,r.jsx)(s.strong,{children:"Users"})," in the dashboard sidebar. Only users with the ",(0,r.jsx)(s.code,{children:"user:write"})," permission can create new users."]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"resetting-the-admin-password",children:"Resetting the Admin Password"}),"\n",(0,r.jsxs)(s.p,{children:["If you lose access to the admin account, stop the service and delete ",(0,r.jsx)(s.code,{children:"~/.routerly/config/users.json"}),". On the next start, the setup page will be available again."]}),"\n",(0,r.jsx)(s.admonition,{type:"warning",children:(0,r.jsxs)(s.p,{children:["Deleting ",(0,r.jsx)(s.code,{children:"users.json"})," removes all dashboard users. API keys and project tokens are not affected."]})})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},8453(e,s,n){n.d(s,{R:()=>a,x:()=>o});var t=n(6540);const r={},i=t.createContext(r);function a(e){const s=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(i.Provider,{value:s},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.