gitoriaLog in with ident

calendar

All repositories: gitoria

ReadmeCodePull requestsReleasesTicketsSettings
Commit6722b72d6722b72ddeploy.sh: never send .git or .gitignore to Byrodinmre6722b72d/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 calendarLogin (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 calendar 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. }
  43. }
  44. showIn = () => {
  45. loggedIn = true
  46. loggedOut = false
  47. selectorClass = 'in'
  48. loginError = ''
  49. hasLoginError = false
  50. }
  51. showOut = () => {
  52. loggedIn = false
  53. loggedOut = true
  54. selectorClass = 'out'
  55. }
  56. // the selector's code (via /login.js and the hidden input) → the server exchanges it
  57. on gotCode(e) {
  58. let code = e.target.value
  59. e.target.value = ''
  60. if (code == null || code == '') { return null }
  61. let r = emit server calendarLogin(code)
  62. if (r == null || r.error != null) {
  63. loginError = r != null ? r.error : 'the login failed'
  64. hasLoginError = true
  65. return null
  66. }
  67. showIn()
  68. navigate('/')
  69. }
  70. on client calendarSignedIn(tag) {
  71. showIn()
  72. navigate('/')
  73. }
  74. on client calendarSignedOut(tag) {
  75. showOut()
  76. navigate('/')
  77. }
  78. on doLogout(e) {
  79. emit server calendarLogOut()
  80. showOut()
  81. navigate('/')
  82. }
  83. // ---- the faces (the trailing `session` is always the server's: hybriel #16) ----
  84. on server calendarLogin(code, session) {
  85. if (session == null) { return { error = 'no session — reload the page' } }
  86. let x = exchangeCode(code)
  87. if (x.error != null) { return { error = x.error } }
  88. let u = ensureUser(x.identity)
  89. if (u == null) { return { error = 'could not store the user' } }
  90. let tag = randomBytes(16)
  91. session.user = { id = u.id }
  92. session.data.tag = tag
  93. emit client calendarSignedIn(tag)
  94. return { ok = true }
  95. }
  96. on server calendarLogOut(session) {
  97. if (session == null) { return { error = 'no session' } }
  98. emit client calendarSignedOut(session.data.tag)
  99. session.user = null
  100. return { ok = true }
  101. }

Branches

Latest commits

  • 6722b72ddeploy.sh: never send .git or .gitignore to Byrodinmre
  • be099807State of 2026-09-27, before the move to gitoriamre