sess.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package sess
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "git.clearsky.net.au/cody/gex.git/sess/jwt"
  7. "git.clearsky.net.au/cody/gex.git/srv"
  8. "git.clearsky.net.au/cody/gex.git/utils"
  9. "time"
  10. )
  11. type Sess struct {
  12. req *srv.Req
  13. res *srv.Res
  14. Expires time.Time
  15. Data map[string]any
  16. }
  17. // config defaults
  18. var TOKENNAME string = "SessToken"
  19. var TIMEOUT time.Duration = 1 * time.Hour
  20. var SECRET string = "secret"
  21. func (sess *Sess) Construct(req *srv.Req, res *srv.Res) {
  22. sess.req = req
  23. sess.res = res
  24. sess.setDefaults()
  25. // check cookie is valid and not expired
  26. cookie, err := req.Cookie(TOKENNAME)
  27. if err != nil {
  28. //utils.Err(err)
  29. return
  30. }
  31. // decode jwt to json bytes
  32. jsonByt, err := jwt.Decode(cookie, SECRET)
  33. if err != nil {
  34. utils.Err(err)
  35. return
  36. }
  37. // decode json bytes to session
  38. err = json.Unmarshal(jsonByt, &sess)
  39. if err != nil {
  40. utils.Err(err)
  41. return
  42. }
  43. // if session token has expired, return default session
  44. if time.Now().After(sess.Expires) {
  45. if time.Now().After(sess.Expires.Add(TIMEOUT)) {
  46. sess.Expires = time.Now().Add(20 * time.Minute)
  47. return
  48. }
  49. fmt.Println("session expired")
  50. sess.setDefaults()
  51. }
  52. }
  53. func (sess *Sess) setDefaults() {
  54. sess.Data = make(map[string]any)
  55. sess.Expires = time.Now().Add(20 * time.Minute)
  56. }
  57. func (sess *Sess) Token() (string, error) {
  58. jsonStr, err := json.Marshal(sess)
  59. if err != nil {
  60. return "", err
  61. }
  62. // encode the json to jwt and set the cookie
  63. token, err := jwt.Encode(jsonStr, SECRET)
  64. if err != nil {
  65. return "", err
  66. }
  67. return token, nil
  68. }
  69. // Saves token to cookie
  70. func (sess *Sess) Save() {
  71. // get the session token
  72. token, err := sess.Token()
  73. if err != nil {
  74. sess.res.Send(err.Error())
  75. return
  76. }
  77. // set the token cookie
  78. sess.res.Cookie(TOKENNAME, token)
  79. }
  80. func GetCtxSess(req *srv.Req) (*Sess, error) {
  81. if req.Ctx["Sess"] == nil {
  82. err := errors.New("no session context, did you add the session middleware?")
  83. utils.Err(err)
  84. return nil, err
  85. }
  86. sess, ok := req.Ctx["Sess"].(*Sess)
  87. if !ok {
  88. err := errors.New("session from context is not of type *Sess")
  89. utils.Err(err)
  90. return nil, err
  91. }
  92. return sess, nil
  93. }