1 // import Cookies from 'js-cookie';
2 import { Err, None, Ok, Option, Result, Some } from "@sniptt/monads";
3 import IsomorphicCookie from "isomorphic-cookie";
4 import jwt_decode from "jwt-decode";
5 import { LoginResponse, MyUserInfo } from "lemmy-js-client";
6 import { BehaviorSubject, Subject } from "rxjs";
7 import { isHttps } from "../env";
8 import { i18n } from "../i18next";
9 import { isBrowser, toast } from "../utils";
22 export class UserService {
23 private static _instance: UserService;
24 public myUserInfo: Option<MyUserInfo> = None;
25 public jwtInfo: Option<JwtInfo> = None;
26 public jwtSub: Subject<Option<JwtInfo>> = new Subject<Option<JwtInfo>>();
27 public unreadInboxCountSub: BehaviorSubject<number> =
28 new BehaviorSubject<number>(0);
29 public unreadReportCountSub: BehaviorSubject<number> =
30 new BehaviorSubject<number>(0);
31 public unreadApplicationCountSub: BehaviorSubject<number> =
32 new BehaviorSubject<number>(0);
34 private constructor() {
38 public login(res: LoginResponse) {
39 let expires = new Date();
40 expires.setDate(expires.getDate() + 365);
41 IsomorphicCookie.save("jwt", res.jwt, { expires, secure: isHttps });
42 console.log("jwt cookie set");
48 this.myUserInfo = None;
49 this.jwtSub.next(this.jwtInfo);
50 IsomorphicCookie.remove("jwt"); // TODO is sometimes unreliable for some reason
51 document.cookie = "jwt=; Max-Age=0; path=/; domain=" + location.host;
52 location.reload(); // TODO may not be necessary anymore
53 console.log("Logged out.");
56 public auth(throwErr = true): Result<string, string> {
57 // Can't use match to convert to result for some reason
58 let jwt = this.jwtInfo.map(j => j.jwt);
60 return Ok(jwt.unwrap());
62 let msg = "No JWT cookie found";
63 if (throwErr && isBrowser()) {
65 toast(i18n.t("not_logged_in"), "danger");
71 private setJwtInfo() {
72 let jwt = IsomorphicCookie.load("jwt");
75 let jwtInfo: JwtInfo = { jwt, claims: jwt_decode(jwt) };
76 this.jwtInfo = Some(jwtInfo);
77 this.jwtSub.next(this.jwtInfo);
81 public static get Instance() {
82 return this._instance || (this._instance = new this());