panel.js 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import { Elysia } from 'elysia'
  2. import { Eta } from "eta"
  3. const eta = new Eta({ views: "./templates" })
  4. import Auth from '../../utils/auth';
  5. import Meteostanice from '../../utils/meteostanice';
  6. import stations from './panel/stations';
  7. import validateTurnstile from '../../utils/validateTurnstile';
  8. import normalizeEmail from '../../utils/normalizeEmail';
  9. export default (langName, lang) => new Elysia({ prefix: "/panel" })
  10. .use(stations(langName, lang))
  11. .get("/", async ({ cookie, redirect, set }) => {
  12. const token = cookie.session.value
  13. const session = await Auth.getSession(token)
  14. if (!session) {
  15. return redirect(`/${langName === "sk" ? `` : `${langName}/`}auth?error=loginNeeded`)
  16. }
  17. const user = Auth.getUser(session.email)
  18. const meteostanice = Meteostanice.getOwned(session.email)
  19. set.headers['content-type'] = 'text/html; charset=utf8'
  20. return eta.render(`${langName}/panel/index`, { user, meteostanice })
  21. })
  22. .get("/settings", async ({ cookie, redirect, set }) => {
  23. const token = cookie.session.value
  24. const session = await Auth.getSession(token)
  25. if (!session) {
  26. return redirect(`/${langName === "sk" ? `` : `${langName}/`}auth?error=loginNeeded`)
  27. }
  28. const user = Auth.getUser(session.email)
  29. set.headers['content-type'] = 'text/html; charset=utf8'
  30. return eta.render(`${langName}/panel/settings`, { siteKey: process.env.TURNSTILE_SITE_KEY, user })
  31. })
  32. .post("/settings", async ({ request, server, cookie, redirect, body, set }) => {
  33. const clientIP = request.headers.get('x-forwarded-for') ?? server.requestIP(request).address
  34. const token = cookie.session.value
  35. const session = await Auth.getSession(token)
  36. if (!session) {
  37. return redirect(`/${langName === "sk" ? `` : `${langName}/`}auth?error=loginNeeded`)
  38. }
  39. const user = Auth.getUser(session.email)
  40. const turnstileResponse = body?.["cf-turnstile-response"]
  41. if (!turnstileResponse) {
  42. set.headers['content-type'] = 'text/html; charset=utf8'
  43. return eta.render(`${langName}/panel/settings`, { siteKey: process.env.TURNSTILE_SITE_KEY, lang, user, error: "turnstile.noToken" })
  44. }
  45. const turnstileValid = await validateTurnstile(turnstileResponse, clientIP)
  46. if (!turnstileValid.success) {
  47. let errorMessage = `turnstile.unavailable`;
  48. if (turnstileValid["error-codes"]?.includes("invalid-input-response"))
  49. errorMessage = `turnstile.invalidResponse`
  50. if (turnstileValid["error-codes"]?.includes("timeout-or-duplicate"))
  51. errorMessage = `turnstile.keyUsedOrExpired`
  52. set.headers['content-type'] = 'text/html; charset=utf8'
  53. return eta.render(`${langName}/panel/settings`, { siteKey: process.env.TURNSTILE_SITE_KEY, lang, user, error: errorMessage })
  54. }
  55. const newName = body?.name
  56. const newEmail = body?.email
  57. if (!normalizeEmail(newEmail)) {
  58. set.headers['content-type'] = 'text/html; charset=utf8'
  59. return eta.render(`${langName}/panel/settings`, { siteKey: process.env.TURNSTILE_SITE_KEY, lang, user, error: "invalidEmail" })
  60. }
  61. const newEmailUser = Auth.getUser(newEmail)
  62. if (newEmailUser && session.email !== newEmail) {
  63. set.headers['content-type'] = 'text/html; charset=utf8'
  64. return eta.render(`${langName}/panel/settings`, { siteKey: process.env.TURNSTILE_SITE_KEY, lang, user, error: "emailTaken", errorDetails: { newEmail } })
  65. }
  66. Auth.editUser(session.email, newName, newEmail)
  67. set.headers['content-type'] = 'text/html; charset=utf8'
  68. return redirect(`/${langName === "sk" ? `` : `${langName}/`}panel`)
  69. })