gitoriaLog in with ident

notes

All repositories: gitoria

ReadmeCodePull requestsReleasesTicketsSettings
Commit1ca2f34d1ca2f34dantcolony#40: history (LOG.md), worker briefs (missions/) and reports moved here from antcolony, numbered per project; old numbers in antcolony docs/mission-map.mdmre1ca2f34d/components/main.hl

3.4 KB

  1. // components/main.hl — THE SHELL: the application header (brand; top right the login: ident's "Log in with
  2. // ident" button or Log out) and the slot every page renders into. All CSS is in styles.hl.
  3. // THE SELECTOR: `<ident-selector key=IDENT_API_KEY>` from <ident>/selector.js, as in gitoria. Choosing an identity
  4. // fires `ident-login` (one-time code); /login.js hands it to the hidden input #identcode, whose `change` goes to the
  5. // face notesLogin (server-side exchange, no reload). The element's class is `in` / `out`; /login.js mirrors it into
  6. // the selector's `loggedIn`.
  7. // LOGIN: a plain link to <ident>/login?key=&return=<public url>/login/callback (project.hl loginCallback).
  8. // After a login or logout in this tab the page is fetched again (navigate('/')): the notes of the session show.
  9. import { navigate } from 'hl:web'
  10. import { siteName } from '../project.hl'
  11. import { identKey, selectorScript, loginHref, userIdOfSession, exchangeCode, ensureUser } from '../users.hl'
  12. import { randomBytes } from 'hl:crypto'
  13. slot = null
  14. session = null
  15. loggedIn = userIdOfSession(session) != null
  16. loggedOut = userIdOfSession(session) == null
  17. buttonHref = loginHref
  18. selectorClass = loggedIn ? 'in' : 'out'
  19. selectorKey = identKey
  20. identScript = selectorScript
  21. loginError = ''
  22. hasLoginError = false
  23. View {
  24. body {
  25. applicationHeader {
  26. a { class = "brand" href = "/" siteName }
  27. userBox { id = "userbox"
  28. identSelector { id = "selector" key = selectorKey class = selectorClass }
  29. if (loggedIn) {
  30. button { id = "logout" type = "button" class = "quiet" "Log out" on click(e) { emit doLogout(e) } }
  31. }
  32. if (loggedOut) {
  33. a { id = "loginbutton" class = "button" href = buttonHref "Log in with ident" }
  34. }
  35. input { id = "identcode" type = "hidden" on change(e) { emit gotCode(e) } }
  36. }
  37. }
  38. if (hasLoginError) { p { id = "loginerror" class = "message banner" loginError } }
  39. main { slot }
  40. script { src = identScript }
  41. script { src = "/login.js" }
  42. script { src = "/md-editor.js" }
  43. script { src = "/notes-offline.js" }
  44. }
  45. }
  46. showIn = () => {
  47. loggedIn = true
  48. loggedOut = false
  49. selectorClass = 'in'
  50. loginError = ''
  51. hasLoginError = false
  52. }
  53. showOut = () => {
  54. loggedIn = false
  55. loggedOut = true
  56. selectorClass = 'out'
  57. }
  58. // the selector's code (via /login.js and the hidden input) → the server exchanges it
  59. on gotCode(e) {
  60. let code = e.target.value
  61. e.target.value = ''
  62. if (code == null || code == '') { return null }
  63. let r = emit server notesLogin(code)
  64. if (r == null || r.error != null) {
  65. loginError = r != null ? r.error : 'the login failed'
  66. hasLoginError = true
  67. return null
  68. }
  69. showIn()
  70. navigate('/')
  71. }
  72. on client notesSignedIn(tag) {
  73. showIn()
  74. navigate('/')
  75. }
  76. on client notesSignedOut(tag) {
  77. showOut()
  78. navigate('/')
  79. }
  80. on doLogout(e) {
  81. emit server notesLogOut()
  82. showOut()
  83. navigate('/')
  84. }
  85. // ---- the faces (the trailing `session` is always the server's: hybriel #16) ----
  86. on server notesLogin(code, session) {
  87. if (session == null) { return { error = 'no session — reload the page' } }
  88. let x = exchangeCode(code)
  89. if (x.error != null) { return { error = x.error } }
  90. let u = ensureUser(x.identity)
  91. if (u == null) { return { error = 'could not store the user' } }
  92. let tag = randomBytes(16)
  93. session.user = { id = u.id }
  94. session.data.tag = tag
  95. emit client notesSignedIn(tag)
  96. return { ok = true }
  97. }
  98. on server notesLogOut(session) {
  99. if (session == null) { return { error = 'no session' } }
  100. emit client notesSignedOut(session.data.tag)
  101. session.user = null
  102. return { ok = true }
  103. }

Branches

Latest commits

  • 1ca2f34dantcolony#40: history (LOG.md), worker briefs (missions/) and reports moved here from antcolony, numbered per project; old numbers in antcolony docs/mission-map.mdmre
  • 2bebebdanotes: Hybriel master ff51cf46 (re-vendor round)mre
  • 3eff126dnotes#3: installable app (manifest + own icon/favicon; notes' own sw.js kept)mre
  • 9883c540deploy.sh: back up live storage/.sessions/.env before every deploy (newest 5 kept)mre
  • eee693b8deploy.sh: never send .git or .gitignore to Byrodinmre
  • c8904061State of 2026-09-27, before the move to gitoriamre